2014-03-04 91 views
0

考慮下面的例子:加密數據與DES - JAVA

String f="A000000000000000"; 
FileInputStream fis = new FileInputStream("C:\\Users\\original.txt"); 
byte[] bytes = DatatypeConverter.parseHexBinary(f); 
SecretKey key = new SecretKeySpec(bytes, 0, bytes.length, "DES"); 

String strDataToEncrypt = new String(); 
String strCipherText = new String(); 
String strDecryptedText = new String(); 

    try{ 

    Cipher desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 
    desCipher.init(Cipher.ENCRYPT_MODE,key); 

      //read from file and transform to String 
      try{ 
      builder = new StringBuilder(); 
      int ch; 
      while((ch = fis.read()) != -1){ 
      builder.append((char)ch); 
      } 
      }catch (IOException e){ 

      } 

    byte[] byteDataToEncrypt = builder.toString().getBytes(); 
    byte[] byteCipherText = desCipher.doFinal(byteDataToEncrypt); 
    strCipherText = new BASE64Encoder().encode(byteCipherText); 

    System.out.println(strCipherText); 

加密的數據不同的是,每次我用相同的密鑰值編譯我,我嘗試了不同的編碼和加密數據總是相同的,那是什麼這裏錯了嗎?

+1

除此之外,此代碼未定義'fis'。意思是這段代碼不會編譯,意味着沒有人可以重現和調查問題,這意味着您將得到的答案要少得多。 – delnan

+0

它的一部分代碼,ofc'fis'被定義。但這裏沒有提到,概率是用加密 – Zame

回答

2

documentation for javax.crypto.Cipher.init說,部分:

如果此cipher要求不能 從給定的密鑰派生的任何算法參數,底層cipher實現 應自己生成所需的參數(使用 提供者特定的默認值或隨機值)

DES CBC(密碼塊鏈接)模式需要初始化向量(IV)。如果你沒有提供一個(你不應該這樣做,因爲它會打開你最多dictionary attacks),會產生一個隨機的。

但是如果你想加密的數據是每次都一樣,你需要使用IvParameterSpec指定IV:

byte[] iv = DatatypeConverter.parseHexBinary("0000000000000000"); 
IvParameterSpec ips = new IvParameterSpec(iv); 
desCipher.init(Cipher.ENCRYPT_MODE, key, iv); 

如果你不讓它產生一個隨機IV,您可以檢索生成IV與desCipher.getIV()

+1

只是補充說,你可以用'desCipher.getIV()'檢索生成的iv。 –

+0

這是非常有意義的,我想如果我不添加一個矢量,他會默認採用「000000」,歡呼聲David – Zame

+0

@FlorentBayle謝謝!這很好。我已經更新了我的答案以包含它。 –