0

I want to implement an encryption/decryption method using RSA public/private keys. I have implemented it in this way


object SecurityUtil {

    private const val ALIAS = "ALIAS"

    fun checkKeys(): Boolean {
        val keyStore: KeyStore = KeyStore.getInstance("AndroidKeyStore").apply {
            load(null)
        }
        val privateKey: PrivateKey? = keyStore.getKey(ALIAS, null) as PrivateKey?
        val publicKey: PublicKey? = keyStore.getCertificate(ALIAS)?.publicKey

        return privateKey != null && publicKey != null
    }

    fun generateKeys() {
        val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore"
        )
        val kgp = KeyGenParameterSpec.Builder(ALIAS, KeyProperties.PURPOSE_DECRYPT)
            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
            .build();

        keyPairGenerator.initialize(kgp)
        keyPairGenerator.genKeyPair()
    }

    private fun getPublicKey(): PublicKey {
        val keyStore: KeyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null)
        return keyStore.getCertificate(ALIAS).publicKey
    }

    private fun getPrivateKey(): PrivateKey {
        val keyStore: KeyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null)
        return keyStore.getKey(ALIAS, null) as PrivateKey
    }

    fun encryptData(text: String): ByteArray {
        val cipher: Cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, getPublicKey())
        return cipher.doFinal(text.toByteArray())
    }

    fun decryptData(encryption: ByteArray): ByteArray {
        val cipher: Cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        cipher.init(Cipher.DECRYPT_MODE, getPrivateKey())
        return cipher.doFinal(encryption)
    }
}

But I am getting an error when I am decrypting the encoded byteArray

Error log

W/System.err: javax.crypto.IllegalBlockSizeException
W/System.err:     at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:619)
W/System.err:     at javax.crypto.Cipher.doFinal(Cipher.java:2056)
W/System.err:     at com.malakapps.keystore_signandverify.SecurityUtil.decryptData(SecurityUtil.kt:60)
W/System.err:     at com.malakapps.keystore_signandverify.MainActivity.onCreate(MainActivity.kt:57)
W/System.err:     at android.app.Activity.performCreate(Activity.java:8290)
W/System.err:     at android.app.Activity.performCreate(Activity.java:8270)
W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4009)
W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4201)
W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loopOnce(Looper.java:226)
W/System.err:     at android.os.Looper.loop(Looper.java:313)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:8663)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
W/System.err: Caused by: android.security.KeyStoreException: Unknown error
W/System.err:     at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:408)
W/System.err:     at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
W/System.err:     at android.security.KeyStoreOperation.finish(KeyStoreOperation.java:127)
W/System.err:     at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.finish(KeyStoreCryptoOperationChunkedStreamer.java:228)
W/System.err:     at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:181)
W/System.err:     at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:609)

What am I doing wrong ? I do not understand what is the issue here. I followed this android documentation AndroidKeyStore

Ankit Verma
  • 496
  • 5
  • 21
  • Is this the whole error message? Or is it *javax.crypto.IllegalBlockSizeException: Data must not be longer than...* RSA only allows encryption of small messages (of the size of the key minus a padding specific value, s. [here](https://crypto.stackexchange.com/a/42100) for OAEP). How large is the key, how large is the message? – Topaco Aug 25 '22 at 14:09
  • @Topaco I have edited the error log. – Ankit Verma Aug 25 '22 at 14:18
  • @Topaco Also I used "Hello" to encrypt it using RSA so I don't think length is a problem – Ankit Verma Aug 25 '22 at 14:43
  • 1
    I can reproduce the issue on my machine. This seems to be a bug already addressed in [this SO post](https://stackoverflow.com/q/36015194/9014097). With the workaround described in the [accepted answer](https://stackoverflow.com/a/36020975/9014097), decryption works on my machine. – Topaco Aug 25 '22 at 15:31
  • @Topaco This does seem to work. – Ankit Verma Aug 25 '22 at 15:53

0 Answers0