android.security.KeyStoreException:不兼容的目的

时间:2016-04-11 14:05:47

标签: android encryption keystore

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

android.security.KeyStoreException:不兼容的目的

执行最后一行时抛出

(其中别名是存储键的名称)。

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");

密钥由以下方法生成:

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:无法抛出密钥库操作。

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

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

似乎问题出在Keymaster图层上。

1 个答案:

答案 0 :(得分:1)

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

  • 签名&验证
  • 加密&解密
  • 密钥包装(仅限Android P +)

更新后的Android Key Keystore System API 23允许您限制密钥的建议(参见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,将该设置设置为您想要做的事情?