android - 使用 KeyStore 进行 RSA 解密时出现间歇性 IllegalBlockSizeException

标签 android encryption keystore

RSA key 是使用以下代码生成的:

RSAKeyGenParameterSpec rsaSpec = new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4);
AlgorithmParameterSpec keyPairGeneratorSpec;

KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(keyAlias, KeyProperties.PURPOSE_DECRYPT)
  .setAlgorithmParameterSpec(rsaSpec)
  .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
  .setDigests(KeyProperties.DIGEST_SHA256);
keyPairGeneratorSpec = specBuilder.build();

try {
  KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA, ANDROID_KEYSTORE);
  keyPairGenerator.initialize(keyPairGeneratorSpec);
  keyPairGenerator.generateKeyPair();
} catch(Exception e) {
  //handle exception
}

然后它用于在 Java 服务器上远程加密,使用:

Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipher.doFinal(data);

然后在设备上,解密是这样完成的:

Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.DECRYPT_MODE, key);
return rsaCipher.doFinal(data);

一小部分时间,解密成功,但大多数时候我得到这个异常:

javax.crypto.IllegalBlockSizeException
  at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
  ...
Caused by: android.security.KeyStoreException: Unknown error
  at android.security.KeyStore.getKeyStoreException(KeyStore.java:695)
  at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
  at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
  at javax.crypto.Cipher.doFinal(Cipher.java:1736)
  ...

我在其他几个 SO 答案中发现了这个异常,包括这个:https://stackoverflow.com/a/36020975/6552833但它似乎并不相关,因为我一开始就没有使用 OAEP 加密。

最佳答案

我遇到了同样的问题。就我而言,我发现了 2 个原因:

  • 服务器端加密以某种方式添加了一个额外的字节,因此加密的 base64 字符串有 257 个字节,而不是密码所期望的 256 个字节。剥离第一个字节使其适用于大多数设备。
  • list 文件设置 - android: allowsbackup ="true" 导致解密在某些设备上失败(发布版本。调试版本很好)。将此设置为 False 可修复它。
<application
android:name=".application.MyApplication"
tools:replace="android:allowBackup"
android:allowBackup="false">

关于android - 使用 KeyStore 进行 RSA 解密时出现间歇性 IllegalBlockSizeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54854418/

相关文章:

android - 谷歌地图 v2 使信息窗口不可点击

android - 如何以正确的方式在服务及其应用程序之间传递数据?

android - 选项卡 fragment 内的 Cardview

php - 在 mysql 数据库中保护用户密码的最佳方法?

amazon-web-services - 无法部署到 Tomcat - 没有 httpd 进程

android - android.test.AndroidTestCase 中的方法 setUp 未被模拟

sql-server - 存储过程 ENCRYPTION 选项取决于构建模式

java - 如何在命令行上指定 keystore 类型?

java - 如何将 keystore 正确打包到 .jar 文件中

android - 如何为 Android MapView 生成指纹?