在 JAVA 中使用 AES/GCM 检测不正确的密钥

2022-01-10 00:00:00 cryptography bouncycastle aes-gcm java jce

我正在使用 AESGCM 模式下使用 BouncyCastle 加密/解密一些文件.
虽然我证明了错误的解密密钥,但也不例外.
我应该如何检查密钥是否不正确?
我的代码是这样的:

I'm using AES to encrypt/decrypt some files in GCM mode using BouncyCastle.
While I'm proving wrong key for decryption there is no exception.
How should I check that the key is incorrect?
my code is this:

    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();

谢谢

推荐答案

在 GCM 模式下没有方法可以检测到不正确的键.您可以检查的是身份验证标签是否有效,这意味着您使用了正确的密钥.问题是,如果身份验证标签不正确,那么这可能表明以下各项(或所有内容的组合,直至并包括完全替换密文和身份验证标签):

There is no method that you can detect incorrect key in GCM mode. What you can check is if the authentication tag validates, which means you were using the right key. The problem is that if the authentication tag is incorrect then this could indicate each of the following (or a combination of all, up to and including the full replacement of the ciphertext and authentication tag):

  1. 使用了不正确的密钥;
  2. 计数器模式加密数据在传输过程中被更改;
  3. 其他经过身份验证的数据已更改;
  4. 身份验证标签本身在传输过程中被更改.

您可以做的是发送额外的数据来识别所使用的密钥.这可能是一个可读的标识符 ("encryption-key-1"),但它也可能是一个 KCV,一个密钥检查值.KCV 通常由使用密钥加密的零块或密钥上的加密安全哈希(也称为指纹)组成.因为零块上的加密会泄漏信息,所以您不应该使用它来识别加密密钥.

What you could do is send additional data to identify the secret key used. This could be a readable identifier ("encryption-key-1") but it could also be a KCV, a key check value. A KCV normally consists of a zero-block encrypted with the key, or a cryptographically secure hash over the key (also called a fingerprint). Because the encryption over a zero block leaks information you should not use that to identify the encryption key.

您实际上可以使用 GCM 模式的 AAD 功能来计算密钥标识数据上的身份验证标签.请注意,您无法区分指纹泄露和使用不正确的密钥.但是指纹被意外损坏的可能性比IV、AAD、密文和认证标签的整个结构要小.

You could actually use the AAD feature of GCM mode to calculate the authentication tag over the key identification data. Note that you cannot distinguish between compromise of the fingerprint and using an incorrect key. It's however less likely that the fingerprint is accidentally damaged than the entire structure of IV, AAD, ciphertext and authentication tag.

相关文章