【问题标题】:Spongy Castle RSA Encryption/Decryption with Android Keystore使用 Android 密钥库的 Spongy Castle RSA 加密/解密
【发布时间】:2018-02-23 00:39:55
【问题描述】:

尝试使用 SpongyCastle 为所有支持的 Android 设备版本上的非对称加密/解密任务提供RSA/ECB/OAEPwithSHA-512andMGF1Padding 的首选加密算法并遇到问题。

加密似乎工作正常。 但是解密证明有些麻烦:

No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding

KeyGen 规范如下:

val generatorSpec = KeyPairGeneratorSpec.Builder(context)
            .setAlias(ALIAS)
            .setSubject(X500Principal(ASYMMETRIC_KEY_COMMON_NAME_PREFIX + ALIAS))
            .setSerialNumber(BigInteger.TEN)
            .setStartDate(creationDate.time)
            .setEndDate(expiryDate.time)
            .build()

val keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore")
keyPairGenerator.initialize(generatorSpec)

keyPairGenerator.generateKeyPair()

我现在从 keyStore 中获取该值并尝试将其用于解密/加密:

private fun rsaEncrypt(data: ByteArray, key: KeyStore.PrivateKeyEntry): ByteArray {
    val encryptionCipher = Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding", "SC")
    encryptionCipher.init(Cipher.ENCRYPT_MODE, key.certificate.publicKey)

    val outputStream = ByteArrayOutputStream()

    val cipherOutputStream = CipherOutputStream(outputStream as OutputStream, encryptionCipher)
    cipherOutputStream.write(data)
    cipherOutputStream.close()

    return outputStream.toByteArray()
}

似乎工作正常,但解密是我的问题所在:

private fun rsaDecrypt(data: ByteArray, key: KeyStore.PrivateKeyEntry): ByteArray {
    val decryptionCipher = Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding", "SC")
    decryptionCipher.init(Cipher.DECRYPT_MODE, key.privateKey)

   // Rest of code for cipher streaming etc. etc.
}

初始化解密密码给我:

java.security.ProviderException: No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding

这很奇怪,因为我的密码实例返回正常并且加密工作正常。

还尝试将提供程序指定为“BC”而不是“SC”,这会给出private exponent cannot be extracted error,我认为这是设计使然。 尝试给出一个支持的算法会破坏密码初始化和通过Provider SC doesn't provide xxx 加密,那么给出了什么?

TLDR: 加密密码与解密具有相同的提供程序。但只有解密中断.... 一定有一些我在这里想念的东西,但我似乎无法找到它。我已经为此工作了一段时间,因此感谢您提供任何帮助!

编辑:出于兴趣,我通过以下方式提供 SpongyCastle:

init { 
    Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
    Security.addProvider(BouncyCastleProvider())
    keyStore.load(null)
}

【问题讨论】:

    标签: android encryption kotlin bouncycastle spongycastle


    【解决方案1】:

    您不能使用由AndroidKeyStore 管理的密钥使用 BC/SC 进行解密,因为私钥内容受到保护并且其参数(例如私有指数)被隐藏,因此任何使用该密钥初始化密码的尝试都会失败.

    使用 SC 的错误消息 No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding 可能是由于库的错误处理不正确,但 BC 的 private exponent cannot be extracted 错误很明显。加密之所以有效,是因为它使用不受保护的公钥。

    您需要使用AndroidKeyStore 进行解密(或者也使用SC/BC 来生成密钥)。

    【讨论】:

    • 谢谢,看来我对这些密钥和密码如何相互配合有点天真。我现在将尝试通过 SC 生成这些密钥,并将它们作为 PrivateKeyEntry 或类似的东西存储/检索到密钥库中。你碰巧有关于如何实现这一目标的任何参考吗?似乎在网上找不到很多示例,最终可能会回到反复试验。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    相关资源
    最近更新 更多