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.
Encryption appears to be working fine. But decryption is proving some trouble:
No provider for RSA/ECB/OAEPwithSHA-512andMGF1Padding
KeyGen spec is as follows:
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:
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.
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?
TLDR: The encryption cipher has the same provider as decryption. 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:
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.
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. 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).