【问题标题】:AES/EAX Crypto with JCE - Mac check in EAX failedAES/EAX 加密与 JCE - EAX 中的 Mac 签入失败
【发布时间】:2019-10-31 12:11:45
【问题描述】:

我正在尝试使用 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 check in EAX failed”。

@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 字节被插入到密文 byte[] 的开头,并在解密期间从密文中检索。
  3. 使用的标签大小为 16 字节。
  4. AesEaxKey 只是一个实现 SecretKey 并委托其所有方法的包装类。

我有一个 AES/GCM/NoPadding 的实现,它使用完全相同的代码,可以完美运行。

我做错了什么?

【问题讨论】:

    标签: java cryptography aes bouncycastle


    【解决方案1】:

    EAX 等 AEAD 模式需要更复杂的 AlgorithmParameterSpec,因为必须指定 nonce(又名 IV)和标记长度(以位为单位)。 Java 自 1.7 以来为 GCM 密码提供了 GCMParameterSpec。 EAX 模式需要相同的数据,显然 Bouncycastle 提供程序也会为 EAX 模式使用 GCMParameterSpec。

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

    【讨论】:

      猜你喜欢
      • 2010-09-13
      • 2022-01-15
      • 1970-01-01
      • 2017-01-26
      • 2012-10-15
      • 2013-09-10
      • 2011-02-11
      • 2014-10-28
      相关资源
      最近更新 更多