The SHA-256 digest not supported for MGF1 on Android using RSA OAEP decryption?

Viewed 523

I'm working with a protocol that uses an algorithm which creates RSA/ECB/OAEPWithSHA-256AndMGF1Padding encrypted messages. For example, this Apple algorithm.

I have the following code

class RsaOaep {

    private val cipher = Cipher.getInstance(transformation)

    companion object {
        // Results in "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"
        private const val transformation = "$KEY_ALGORITHM_RSA/$BLOCK_MODE_ECB/$ENCRYPTION_PADDING_RSA_OAEP"

        // Note that MGF1ParameterSpec.SHA256 is not supported on Android!!!
        private val spec = OAEPParameterSpec("SHA-256","MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)
    }

    fun wrap(publicKey: Key, data: ByteArray): ByteArray {
        val secretKey = SecretKeyGenerator().generateSecretKey()
        cipher.init(Cipher.WRAP_MODE, publicKey, spec)
        return cipher.wrap(secretKey)
    }

    fun decrypt(wrappedKey: ByteArray, privateKey: Key): ByteArray {
        cipher.init(Cipher.UNWRAP_MODE, privateKey, spec)
        return cipher.unwrap(wrappedKey, SecretKeyGenerator.KEY_ALGORITHM, Cipher.SECRET_KEY)
    }
}

But my Android application can't decrypt them. I'm getting the following error.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example, PID: 9813
    java.security.InvalidAlgorithmParameterException: Unsupported MGF1 digest: SHA-256. Only SHA-1 supported
        at android.security.keystore.AndroidKeyStoreRSACipherSpi$OAEPWithMGF1Padding.initAlgorithmSpecificParameters(AndroidKeyStoreRSACipherSpi.java:228)
        at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:147)
        at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2980)
        at javax.crypto.Cipher.tryCombinations(Cipher.java:2891)
        at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796)
        at javax.crypto.Cipher.chooseProvider(Cipher.java:773)
        at javax.crypto.Cipher.init(Cipher.java:1288)
        at javax.crypto.Cipher.init(Cipher.java:1223)
        at com.example.RsaOaep.decrypt(RsaOaep.kt:21)

This limitation is hardcoded into the Android source code.

  • Why is that the case?
  • When will it change? ... and
  • How can I work around it?
0 Answers
Related