猿问

尝试在 GCM 模式下解密消息时出现 AEADBadTagException

我正在编写一个应用程序,它有很多安全限制:它需要安全加密存储文件,并且必须能够解密它们。此外,操作员需要能够在没有应用程序的情况下解密文件。

为了存档,我KeyPair在我的 PC 上生成了一个,将公共部分放在我的应用程序中,在应用程序中生成一个AES SecretKey密钥,用我的公钥加密并保存它(用于操作员目的),然后将未加密的密钥放在AndroidKeyStore.

要加密消息,我收到SecretKeyfrom KeyStore,加密我的消息,获取IVI used 和 encryptedSecretKey,然后按照定义的顺序将它们写入字节数组 (iv->encryptedSecretKey->encryptedMessage)。

要解密,我反向尝试相同的方法:获取字节数组,读取 iv 和 encryptedSecretKey,并将其余的 (encryptedMessage) 传递给我的密码进行解密。问题是,这cipher.doFinal(encryptedMessage)是抛出 javax.crypto.AEADBadTagExceptionandroid.security.KeyStoreException: Signature/MAC verification failed.

我已经检查过加密的消息和我想要解密的消息是完全一样的。我不知道我做错了什么。

顺便说一下,minSdkVersion 是 25,所以比 Marshmallow 高

更新

  1. 修复Cipher.DECRYPT_MODEENCRYPT_MODE将 SecretKey thx 保存到 James K Polk 的评论

  2. 如果我从BlockMode GCMBlockMode切换CBC(并更改GCMParameterSpecIvParamterSpec但失去 GCM 模式的验证,它会起作用。


qq_笑_17
浏览 1312回答 1
1回答

弑天下

操作员界面至少存在两个问题。首先,您使用错误的密码模式 RSA 加密密钥:您在应该使用加密时使用了 DECRYPT 模式。其次,您使用的是没有任何填充的 RSA。您需要使用真正的填充模式,建议使用其中一种 OEAP 填充模式。调整用于保存结果的缓冲区大小时,加密端发生错误:ByteBuffer buffer = ByteBuffer.allocate(IV_BIT_LEN + encryptedSecretKey.length + cryptedBytes.length);分配太多空间。IV_BIT_LEN可能应该更改为IV_SIZE以获得正确大小的ByteBuffer.最后一个错误是GCMParameterSpec在解密端设置 时没有考虑到 GCM 认证标签长度。您在此行中初始化了标签长度GCMParameterSpec parameterSpec = new GCMParameterSpec(IV_BIT_LEN, iv);但这是不正确的,标签长度与 IV 无关。由于您没有在加密端明确设置 GCMParameterSpec,因此您获得了默认标签长度,恰好是 128。您可以通过调用cipher.getParameters().getParameterSpec(GCMParameterSpec.class)获取参数规范来检索加密端的标签长度 。从中您可以检索标签长度和 iv。您可能应该将标签长度(16 字节 = 128 位)视为硬编码常量,而不是传输它。接收器应该类似地假设标签长度是 128 位。
随时随地看视频慕课网APP

相关分类

Java
我要回答