Invalid private RSA key: Keystore operation failed

Viewed 295

I receive this error:

com.nimbusds.jose.JOSEException: Invalid private RSA key: Keystore operation failed

And my java.class:

public class MyClass {


private static final String ANDROID_PROVIDER = "AndroidKeyStore";

@RequiresApi(api = Build.VERSION_CODES.M)
public static PublicKey getPublicKeyAndCreateKeypairIfNotExists(String alias) throws GeneralSecurityException, IOException {

    KeyStore keyStore = KeyStore.getInstance(ANDROID_PROVIDER);
    keyStore.load(null);
    if (!keyStore.containsAlias(alias) || keyStore.getCertificate(alias) == null) {

        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .build();
        KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_PROVIDER);
        generator.initialize(spec);
        generator.generateKeyPair();
    }
    return keyStore.getCertificate(alias).getPublicKey();
}

@RequiresApi(api = Build.VERSION_CODES.M)
public static PrivateKey getSecretKey(String alias) throws GeneralSecurityException, IOException {
    KeyStore.Entry entry;
    //Get Android KeyStore
    KeyStore ks = KeyStore.getInstance(ANDROID_PROVIDER);
    // Weird artifact of Java API.  If you don't have an InputStream to load, you still need to call "load", or it'll crash.
    ks.load(null);
    // Load the key pair from the Android Key Store
    entry = ks.getEntry(alias, null);
    KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)entry;
    PrivateKey privateKey = privateKeyEntry.getPrivateKey();
    return privateKey;
}


public static String createJWT(String alias) throws JSONException, GeneralSecurityException, IOException, JOSEException {
    // 
    RSASSASigner signer = new RSASSASigner(getSecretKey(alias));
    //signer.getJCAContext().setProvider(hsmProvider);

    //
    SignedJWT jwt = new SignedJWT(
            new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(alias).build(),
            new JWTClaimsSet.Builder().subject("alice").build());

    jwt.sign(signer);
    String jwtString = jwt.serialize();

    return jwtString;
}

}

The error appears specifically when executing the createJWT method on the line:

jwt.sign(signer);

Apparently the creation of the Keypair is satisfactory, since I have previously tested it and it does not give any error, even with ENCRYPT and DECRYPT it works perfectly. The problem is in the createJWT() method. I really don't know what I'm doing wrong.

Thanks in advance

1 Answers

I ran into this same issue. when i looked into the end of stack trace, the exception was

Caused by: android.security.KeyStoreException: **Incompatible padding mode**

And fixed by setting Signature mode for it, while generating the key

setSignaturePaddings(SIGNATURE_PADDING_RSA_PKCS1)
Related