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; } }
额外注意点
- 原加密方法里的
cipherOutputStream.write(Base64.decode(textToEncrypt, Base64.DEFAULT));逻辑存在问题:如果textToEncrypt是普通明文,不需要先做Base64解码,直接转字节数组即可,否则会导致乱码或加密失败。 - 如果你的项目必须使用BouncyCastle提供商,可以明确指定
Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"),前提是你已经引入了BouncyCastle库。 - 你不需要尝试把
OpenSSLRSAPublicKey转换成AndroidKeyStoreRSAPublicKey——后者只能由AndroidKeyStore生成,无法通过模和指数手动创建,这也是你找不到相关转换方法的核心原因。
内容的提问来源于stack exchange,提问作者ChristianoBolla
相关产品推荐
相关产品推荐

