我正在编写一个应用程序,它有很多安全限制:它需要安全加密存储文件,并且必须能够解密它们。此外,操作员需要能够在没有应用程序的情况下解密文件。为了存档,我KeyPair在我的 PC 上生成了一个,将公共部分放在我的应用程序中,在应用程序中生成一个AES SecretKey密钥,用我的公钥加密并保存它(用于操作员目的),然后将未加密的密钥放在AndroidKeyStore.要加密消息,我收到SecretKeyfrom KeyStore,加密我的消息,获取IVI used 和 encryptedSecretKey,然后按照定义的顺序将它们写入字节数组 (iv->encryptedSecretKey->encryptedMessage)。要解密,我反向尝试相同的方法:获取字节数组,读取 iv 和 encryptedSecretKey,并将其余的 (encryptedMessage) 传递给我的密码进行解密。问题是,这cipher.doFinal(encryptedMessage)是抛出 javax.crypto.AEADBadTagException由android.security.KeyStoreException: Signature/MAC verification failed.我已经检查过加密的消息和我想要解密的消息是完全一样的。我不知道我做错了什么。顺便说一下,minSdkVersion 是 25,所以比 Marshmallow 高更新:修复Cipher.DECRYPT_MODE了ENCRYPT_MODE将 SecretKey thx 保存到 James K Polk 的评论如果我从BlockMode GCMBlockMode切换CBC(并更改GCMParameterSpec为IvParamterSpec但失去 GCM 模式的验证,它会起作用。
1 回答
弑天下
TA贡献1818条经验 获得超8个赞
操作员界面至少存在两个问题。首先,您使用错误的密码模式 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 位。
添加回答
举报
0/150
提交
取消