You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将包装后的AES密钥导入Android Keystore时触发-1000错误排查

Android Keystore导入RSA包装AES密钥报错-1000问题解决

问题详情

已生成RSA密钥对与AES密钥,通过RSA公钥包装AES密钥后,尝试将加密后的AES密钥导入Android Keystore时触发错误,报错代码行:

keyStore.setEntry(IMPORTED_KEY_ALIAS, wrappedKeyEntry, null);

错误信息:

java.security.KeyStoreException: Failed to import wrapped key. Keystore error code: -1000
at android.security.keystore2.AndroidKeyStoreSpi.setWrappedKeyEntry(AndroidKeyStoreSpi.java:983)

已确认包装后的密钥生成正确,相关代码如下:

private KeyPair getOrCreateKeyPair() throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);
    if (!keyStore.containsAlias(KEY_ALIAS)) {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
        keyPairGenerator.initialize(
                new KeyGenParameterSpec.Builder(KEY_ALIAS,
                        KeyProperties.PURPOSE_WRAP_KEY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                        .setKeySize(2048)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                        .build());
        return keyPairGenerator.generateKeyPair();
    } else {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
        return new KeyPair(privateKeyEntry.getCertificate().getPublicKey(), privateKeyEntry.getPrivateKey());
    }
}

private SecretKey generateAESKey() throws Exception {
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    keyGenerator.init(256);
    return keyGenerator.generateKey();
}
private byte[] wrapKey(PublicKey publicKey, SecretKey aesKey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding", "BC");
    cipher.init(Cipher.WRAP_MODE, publicKey);
    return cipher.wrap(aesKey);
}

private void importWrappedKey(byte[] wrappedKey) throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null, null);

    AlgorithmParameterSpec spec = new KeyGenParameterSpec.Builder(IMPORTED_KEY_ALIAS,
            KeyProperties.PURPOSE_WRAP_KEY )
            .setDigests(KeyProperties.DIGEST_SHA256)
            .build();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        WrappedKeyEntry wrappedKeyEntry = new WrappedKeyEntry(wrappedKey, KEY_ALIAS, "RSA/ECB/OAEPPadding", spec);
        keyStore.setEntry(IMPORTED_KEY_ALIAS, wrappedKeyEntry, null);
    }
}

问题根源分析

Keystore错误码-1000对应KEYSTORE_ERROR_UNKNOWN,但结合代码细节,核心问题集中在以下几点:

  • 跨提供者兼容性问题:使用BouncyCastle(BC)提供者执行RSA-OAEP包装,与Android Keystore的算法参数不兼容。
  • RSA密钥用途缺失:未配置PURPOSE_UNWRAP_KEY,导致Keystore无法用该RSA密钥解包导入的AES密钥。
  • AES密钥导入参数不完整:未明确指定AES密钥的算法类型、密钥大小,以及与包装操作匹配的OAEP参数。

修复方案

1. 调整RSA密钥生成参数

补充解包用途,并明确OAEP使用的摘要算法:

private KeyPair getOrCreateKeyPair() throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);
    if (!keyStore.containsAlias(KEY_ALIAS)) {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
        keyPairGenerator.initialize(
                new KeyGenParameterSpec.Builder(KEY_ALIAS,
                        KeyProperties.PURPOSE_WRAP_KEY | KeyProperties.PURPOSE_UNWRAP_KEY)
                        .setKeySize(2048)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                        .setDigests(KeyProperties.DIGEST_SHA256)
                        .build());
        return keyPairGenerator.generateKeyPair();
    } else {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
        return new KeyPair(privateKeyEntry.getCertificate().getPublicKey(), privateKeyEntry.getPrivateKey());
    }
}

2. 使用系统兼容的Cipher包装密钥

移除BC提供者,改用系统默认实现,并明确OAEP参数:

private byte[] wrapKey(PublicKey publicKey, SecretKey aesKey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
    OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
    cipher.init(Cipher.WRAP_MODE, publicKey, oaepSpec);
    return cipher.wrap(aesKey);
}

3. 完善AES密钥导入配置

明确AES密钥属性,并匹配包装时的OAEP参数:

private void importWrappedKey(byte[] wrappedKey) throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null, null);

    KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(IMPORTED_KEY_ALIAS,
            KeyProperties.PURPOSE_WRAP_KEY)
            .setKeySize(256)
            .setAlgorithmParameterSpec(new AESKeyGenParameterSpec(256))
            .setDigests(KeyProperties.DIGEST_SHA256)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
            .build();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
        WrappedKeyEntry wrappedKeyEntry = new WrappedKeyEntry(wrappedKey, KEY_ALIAS, "RSA/ECB/OAEPPadding", oaepParams, spec);
        keyStore.setEntry(IMPORTED_KEY_ALIAS, wrappedKeyEntry, null);
    }
}

额外注意事项

  • 确保测试设备运行Android 10及以上版本(Keystore2的最低适配版本)。
  • 导入前检查IMPORTED_KEY_ALIAS是否已存在,避免重复导入引发冲突。
  • 所有Keystore操作需在同一实例上下文执行,避免跨实例权限问题。

内容的提问来源于stack exchange,提问作者acrux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 21:23:12