#1049·jjwt

AndroidKeyStore RSA keys not able to be used for signing

Author: aeri-riCreated May 24, 2026Updated Aug 24, 2026

Describe the bug Using an AndroidKeyStore keypair's private key doesn't allow signing of a jwt. I've tried using the BouncyCastle dependencies as mentioned in the main readme as well. The following is the error I get.

io.jsonwebtoken.security.SignatureException: Unable to compute PS256 signature with JCA algorithm 'RSASSA-PSS' using key {class: android.security.keystore2.AndroidKeyStoreRSAPrivateKey, algorithm: RSA, format: null}: Signature callback execution failed: No installed provider supports this key: android.security.keystore2.AndroidKeyStoreRSAPrivateKey

To Reproduce Steps to reproduce the behavior:

  1. Generate key pair using RSA with PSS for signature padding and SHA256 digest.
val kpg: KeyPairGenerator =
            KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")

        val KEY_ALIAS = "example"
        kpg.initialize(

            KeyGenParameterSpec.Builder(
                KEY_ALIAS,
                KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY or KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
            )
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
                .setKeySize(2048)
                .build()
        )

        kpg.generateKeyPair()
  1. Get key pair private and public key for use in creating a jwt.
var keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
            load(null) 
        }
        var entry = keyStore.getEntry("example", null) as? KeyStore.PrivateKeyEntry
        var keyPair = KeyPair(entry?.certificate?.publicKey, entry?.privateKey)
        if (entry == null || keyPair == null) {
            try {
                generateKeys();
                keyStore = KeyStore.getInstance("AndroidKeyStore").apply {
                    load(null) 
                }
                entry = keyStore.getEntry("example", null) as? KeyStore.PrivateKeyEntry
                keyPair = KeyPair(entry?.certificate?.publicKey, entry?.privateKey)
            } catch (e: Exception) {
                //
            }
        }


        pubKey = entry?.certificate?.publicKey as RSAPublicKey
        privKey = entry?.privateKey as PrivateKey
  1. Use public key and private key in creating and signing a jwt.
val jwk = Jwks.builder()
                .key(pubKey).build()
            val jws = Jwts.builder()
                .header()
                .jwk(jwk)
                .and().id(Uuid.random().toString())
                .claims()
                .add("random","example")
                .and()
                .signWith(privKey, Jwts.SIG.PS256)
                .compact()

Expected behavior The jwt should be able to be signed with the AndroidKeyStore private key. I'm able to sign with the private key using the Signature instance in the following way:

val s = Signature.getInstance("SHA256withRSA/PSS")
                .apply {
                initSign(privKey)
                update(payload)
            }
val signature: ByteArray = s.sign()