带有JCE的AES / EAX加密-EAX中的Mac检查失败

时间:2019-06-17 21:26:11

标签: java cryptography aes bouncycastle

我正在尝试使用AES / EAX / NoPadding执行加密/解密。由于没有BouncyCastle似乎无法使用EAX,因此已将BC添加为提供程序。

当我尝试加密“ Hello World!”时,它似乎已经成功加密。

@NotNull
@Override
public byte[] encrypt(@NotNull Key key, @NotNull byte[] plain, @Nullable byte[] authentication) throws CryptoException {
    try {
        final AesEaxKey aesEaxKey = (AesEaxKey) key;
        final Cipher cipher = Cipher.getInstance(getCipherAlgorithm(), BouncyCastleProvider.PROVIDER_NAME);
        final byte[] cipherText = new byte[getIvSize(aesEaxKey) + plain.length + getTagSize()];
        final byte[] iv = randomIv(aesEaxKey);

        System.arraycopy(iv, 0, cipherText, 0, getIvSize(aesEaxKey));
        cipher.init(Cipher.ENCRYPT_MODE, aesEaxKey, getParameterSpec(iv));

        if (authentication != null && authentication.length != 0) {
            cipher.updateAAD(authentication);
        }

        cipher.doFinal(plain, 0, plain.length, cipherText, getIvSize(aesEaxKey));
        return cipherText;
    } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchProviderException |
            InvalidKeyException | BadPaddingException | IllegalBlockSizeException | ShortBufferException e) {
        throw new CryptoException(e.getMessage(), e);
    }
}

当我尝试解密密文时,它会引发“ Mac在EAX中检查失败”。

@NotNull
@Override
public byte[] decrypt(@NotNull Key key, @NotNull byte[] cipherText, @Nullable byte[] authentication) throws CryptoException {
    try {
        final AesEaxKey aesEaxKey = (AesEaxKey) key;
        final Cipher cipher = Cipher.getInstance(getCipherAlgorithm(), BouncyCastleProvider.PROVIDER_NAME);
        cipher.init(Cipher.DECRYPT_MODE, aesEaxKey, getParameterSpec(cipherText, 0, getIvSize(aesEaxKey)));
        if (authentication != null && authentication.length != 0) {
            cipher.updateAAD(authentication);
        }
        return cipher.doFinal(cipherText, getIvSize(aesEaxKey), cipherText.length - getIvSize(aesEaxKey));
    } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException |
            InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
        throw new CryptoException(e.getMessage(), e);
    }
}

详细信息:

  1. getParameterSpec()返回带有IV的IvParameterSpec的实例。
  2. 在加密过程中,将IV字节插入密文字节[]的开头,并在解密期间从密文中检索。
  3. 正在使用的标签大小为16个字节。
  4. AesEaxKey只是一个包装类,它实现SecretKey并委托其所有方法。

我有一个AES / GCM / NoPadding实现,它使用完全相同的完全相同的代码,可以很好地工作。

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

诸如EAX的AEAD模式需要更复杂的AlgorithmParameterSpec,因为必须同时指定现时(即IV)和标记长度(以位为单位)。从1.7开始,Java已为GCM密码提供了GCMParameterSpec。 EAX模式需要相同的数据,显然Bouncycastle提供程序也将GCMParameterSpec用于EAX模式。

请注意,对于GCMParameterSpec,标记长度是以位为单位指定的,而为了调整数组大小,则需要以字节为单位指定标记长度。