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

Android公钥加密报错:Unsupported key type: OpenSSLRSAPublicKey

问题本质解析

你碰到的这个InvalidKeyException核心原因很明确:你用了AndroidKeyStore专属的Cipher实现来加密一个非AndroidKeyStore托管的公钥。

具体来说,你通过KeyFactory.getInstance("RSA").generatePublic()生成的OpenSSLRSAPublicKey是标准JCE的密钥实现,并没有被托管在AndroidKeyStore中;而你初始化Cipher时指定了"AndroidKeyStoreBCWorkaround"提供商,这个提供商的Cipher仅支持操作存储在AndroidKeyStore里的密钥(也就是你通过createKeyPairsOrGetPublicKey生成的AndroidKeyStoreRSAPublicKey类型),所以会直接抛出不支持密钥类型的异常。

解决方案

解决思路很简单:加密外部获取的公钥时,使用标准的JCE Cipher实现,不要指定AndroidKeyStore相关的提供商。

你只需要修改加密方法中的Cipher初始化代码,移除"AndroidKeyStoreBCWorkaround"参数即可——这样会自动使用系统默认的JCE提供商(比如OpenSSL),它能完美处理OpenSSLRSAPublicKey类型的密钥。

修改后的加密方法代码
// encrypt a text with a public key
public static String encryptWithPublicKey(PublicKey publicKey, String textToEncrypt) {
    try {
        // 移除AndroidKeyStoreBCWorkaround提供商,使用标准RSA加密参数
        Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 修正:直接将明文转字节数组(原代码的Base64解码逻辑不符合普通明文加密场景)
        byte[] plainText = textToEncrypt.getBytes(StandardCharsets.UTF_8);
        byte[] encryptedBytes = inCipher.doFinal(plainText);
        return Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}
额外注意点
  1. 原加密方法里的cipherOutputStream.write(Base64.decode(textToEncrypt, Base64.DEFAULT));逻辑存在问题:如果textToEncrypt是普通明文,不需要先做Base64解码,直接转字节数组即可,否则会导致乱码或加密失败。
  2. 如果你的项目必须使用BouncyCastle提供商,可以明确指定Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"),前提是你已经引入了BouncyCastle库。
  3. 你不需要尝试把OpenSSLRSAPublicKey转换成AndroidKeyStoreRSAPublicKey——后者只能由AndroidKeyStore生成,无法通过模和指数手动创建,这也是你找不到相关转换方法的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:40:42