2012-09-01 18 views
3

我正在使用AES使用BouncyCastle加密/解密GCM模式中的某些文件。
雖然我證明錯誤的解密密鑰,但沒有例外。
我應該如何檢查鑰匙是否有誤?
我的代碼是這樣的:在JAVA中使用AES/GCM檢測不正確的密鑰

SecretKeySpec incorrectKey = new SecretKeySpec(keyBytes, "AES"); 
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); 
    Cipher   cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); 
    byte[] block = new byte[1048576]; 
    int i; 

    cipher.init(Cipher.DECRYPT_MODE, incorrectKey, ivSpec); 

    BufferedInputStream fis=new BufferedInputStream(new ProgressMonitorInputStream(null,"Decrypting ...",new FileInputStream("file.enc"))); 
    BufferedOutputStream ro=new BufferedOutputStream(new FileOutputStream("file_org"));   
    CipherOutputStream dcOut = new CipherOutputStream(ro, cipher); 

    while ((i = fis.read(block)) != -1) { 
     dcOut.write(block, 0, i); 
    } 

    dcOut.close(); 
    fis.close(); 

感謝

+1

這將是非常好的,如果你會接受一些更多的答案和跟進你的問題4r1y4n(這將是Ariyan我想) –

+1

是否有一個特定的原因,你爲什麼不接受加密問題的答案,4r1y4n,或他們是否逃避了你的注意?你沒有接受任何4連續。 –

+0

請注意:Java 7中的AEAD模式與CipherInputStream結合不受完整性保護:https://github.com/binwiederhier/syncany/issues/28#issuecomment-36337529 – binwiederhier

回答

-6

您正在使用NoPadding。對於加密和解密,將其更改爲PKCS7Padding。如果使用了錯誤的密鑰,那麼填充將幾乎肯定無法按預期解密,並且將引發InvalidCipherTextException

+1

1)GCM是一種流模式,所以它不需要填充2)依靠填充進行完整性檢查是一個非常糟糕的主意。這很可能是你打開填充神諭的方式。 3)GCM有一個集成的MAC,它已經負責你需要的任何完整性檢查。 – CodesInChaos

+0

問題是關於識別不正確的密鑰,而不是完整性檢查。使用填充對於那個特定的問題很好。你對GCM是正確的,我的錯誤。 – rossum

+0

這是一個非常罕見的延時羅斯姆,我確信我做得更多。你介意我是否收藏了我罕見的失誤? :) –

4

沒有方法可以在GCM模式下檢測到不正確的鍵。您可以檢查的是驗證標記是否有效,這意味着您使用的是正確的密鑰。問題是,如果認證標籤不正確,那麼這可能表明以下每一項(或所有的組合,直至幷包括全面替代對密文和認證標籤的):

  1. 不正確的密鑰正在使用;
  2. 計數器模式加密數據在傳輸過程中被更改;
  3. 額外的認證數據已被更改;
  4. 認證標籤本身在運輸過程中被更改。

你可以做的是發送額外的數據來識別使用的密鑰。這可能是一個可讀的標識符("encryption-key-1"),但它也可能是KCV,一個關鍵檢查值。 KCV通常由用密鑰加密的零塊或密鑰(也稱爲指紋)上的密碼安全散列組成。由於零塊上的加密泄漏了信息,因此不應使用它來標識加密密鑰。

您實際上可以使用GCM模式的AAD功能來計算密鑰標識數據上的認證標籤。請注意,您無法區分是否損壞指紋和使用不正確的密鑰。然而,與IV,AAD,密文和認證標籤的整個結構相比,指紋不太可能被意外損壞。

相關問題