安卓.security.KeyStoreException : Incompatible purpose

标签 android encryption keystore

我无法在 Android 上解密之前加密的字符串。问题主要出现在运行 Android 6 Marshmallow 的索尼设备(Xperia Z5 和 Xperia Z5 Compact)上。

android.security.KeyStoreException:目的不兼容

在执行最后一行时抛出(其中别名是存储 key 的名称)。

KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
output.init(Cipher.DECRYPT_MODE, privateKey);

KeyStore本身是通过

获取的
KeyStore.getInstance("AndroidKeyStore");

key 通过以下方法生成:

private static void createKey(String alias, String subject, KeyStore keyStore, BigInteger serialNumber, Date startDate, Date endDate, String algorithm, String keyStoreProvider, Context context)
            throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    if (keyStore.containsAlias(alias)) {
        // Key already exists.
        return;
    }

    // Generate keys.
    KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
            .setAlias(alias)
            .setSubject(new X500Principal(subject))
            .setSerialNumber(serialNumber)
            .setStartDate(startDate)
            .setEndDate(endDate)
            .build();

    KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm, keyStoreProvider);
    generator.initialize(spec);

    KeyPair keyPair = generator.generateKeyPair();
}

其中算法是“RSA”,keyStoreProvider 是“AndroidKeyStore”。

堆栈跟踪部分:

android.security.KeyStoreException: Incompatible purpose
       at android.security.KeyStore.getKeyStoreException(KeyStore.java:636)
       at android.security.KeyStore.getInvalidKeyException(KeyStore.java:716)
       at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:53)
       at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:263)
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:108)
       at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:612)
       at javax.crypto.Cipher.tryCombinations(Cipher.java:532)
       at javax.crypto.Cipher.getSpi(Cipher.java:437)
       at javax.crypto.Cipher.init(Cipher.java:815)
       at javax.crypto.Cipher.init(Cipher.java:774)

异常导致java.security.InvalidKeyException: Keystore operation failed to be throw

我无法直接在我的设备上重现错误(崩溃信息来自 Crashlytics)。

遵循 KeyStore 的堆栈跟踪和代码:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/keystore/java/android/security/KeyStore.java

看来问题出在 Keymaster 层。

最佳答案

Android Keystore System , purpose 引用如何使用 key 。非对称 key 的可能选项是:

  • 签名和验证
  • 加密与解密
  • 按键包装(仅限 Android P+)

针对 SDK 23 更新的 Android Keystore 系统 API 确实允许您限制对您的 key 的建议(请参阅 KeyProperties)。

新 API 的示例:

KeyGenParameterSpec.Builder keyGenParameterSpecBuilder = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(algorithmDefinition.keyLengthBit, algorithmDefinition.publicExponent))
                .setRandomizedEncryptionRequired(meta.randomizedEncryptionRequired)
                .setBlockModes(algorithmDefinition.blockMode)
                .setUserAuthenticationRequired(meta.userAuthenticationRequired)
                .setKeySize(algorithmDefinition.keyLengthBit);

可能存在设备错误,该设备运行 SDK 23 并且您使用旧 API,但设备要求您使用新 API,将 prupose 设置为您想要执行的操作?

关于安卓.security.KeyStoreException : Incompatible purpose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36551038/

相关文章:

python - AES 加密中的 IV must be 16 bytes long 错误

java - 是否可以在测试用例中注册接收器?

android - Context.startForegroundService() 然后没有调用 Service.startForeground() 即使我停止了服务

node.js - 使用带有 Node 的 ursa 加密和解密字符串会引发解码错误

C语言凯撒密码——加密与解密

java - Maven 错误 : (repeated) java. security.InvalidAlgorithmParameterException: trustAnchors 参数必须为非空

java - 在存储之前和从 KeyStore 检索之后,SecretKey 的 Base64 编码值不同

java - 如何将 java KeyStore 转换为 PKCS7 .p7b 文件?

android - 在 recyclerview 中显示图像的占位符

android - ListView 复选框保存状态