简体   繁体   English

使用 Android Keystore 的 Spongy Castle RSA 加密/解密

[英]Spongy Castle RSA Encryption/Decryption with Android Keystore

Attempting to use SpongyCastle to provide the preferred encryption algorithm of RSA/ECB/OAEPwithSHA-512andMGF1Padding for Asymmetric encryption/decryption tasks on all supported Android device versions and having issues.尝试使用 SpongyCastle 提供首选加密算法RSA/ECB/OAEPwithSHA-512andMGF1Padding用于所有受支持的 Android 设备版本上的非对称加密/解密任务,但存在问题。

Encryption appears to be working fine.加密似乎工作正常。 But decryption is proving some trouble:但是解密证明了一些麻烦:

No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding

KeyGen spec is as follows: 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()

I'm now grabbing this value from the keyStore and trying to use it for decryption/encryption:我现在从 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()
}

This appears to work fine, however decryption is where my issue lies:似乎工作正常,但是解密是我的问题所在:

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.
}

initialising the decryptionCipher is giving me:初始化解密密码给了我:

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

Which is strange due to my cipher instance returning fine and encryption working fine.由于我的密码实例返回正常并且加密工作正常,这很奇怪。

Also tried specifying the provider as “BC” rather than “SC” which gives a private exponent cannot be extracted error which I'm thinking is by design.还尝试将提供者指定为“BC”而不是“SC”,这会private exponent cannot be extracted error ,我认为这是设计使然。 Trying to give a algorithm that isn't supported will break on the cipher initialisation and Encryption via Provider SC doesn't provide xxx so what gives?试图给支持将打破经由密码初始化和加密算法验证Provider SC doesn't provide xxx那么怎么办?

TLDR: The encryption cipher has the same provider as decryption. TLDR:加密密码与解密具有相同的提供者。 But only decryption breaks.... There has to be something I'm missing here but can't seem to put my finger on it.但只有解密中断......这里一定有我遗漏的东西,但似乎无法将我的手指放在上面。 I've been working on this a while so any help is appreciated!我一直在这方面工作一段时间,所以任何帮助表示赞赏!

Edit: For interest I'm providing SpongyCastle through:编辑:出于兴趣,我通过以下方式提供 SpongyCastle:

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

You can not decrypt with BC/SC using a key managed by AndroidKeyStore because the private key content is protected and its parameters (such as private exponent) are hidden, so any attempt to initialize a cipher with that key will fail.您无法使用AndroidKeyStore管理的密钥通过 BC/SC 进行解密,因为私钥内容受到保护并且其参数(例如私有指数)是隐藏的,因此任何使用该密钥初始化密码的尝试都将失败。

The error message No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding using SC is probably due to an incorrect error handling by the library, but the private exponent cannot be extracted error for BC is clear.错误消息No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding using SC 可能是由于库的错误处理不正确,但 BC 的private exponent cannot be extracted错误是明确的。 Encryption works because it uses the public key, which is not protected.加密之所以有效,是因为它使用不受保护的公钥。

You need to use AndroidKeyStore for decryption (or use SC/BC also to generate the keys).您需要使用AndroidKeyStore进行解密(或者也使用 SC/BC 来生成密钥)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM