Save and Retrieve KeyPair in AndroidKeystore

10,607

With AndroidKeyStore is needed to use KeyGenParameterSpec.Builder to generate the keys. Also use AndroidKeyStore instead of SC. You can use the following code

Generate the keys (Android>=23)

KeyPairGenerator kpg = KeyPairGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");

kpg.initialize(new KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                .setKeySize(keySize)
                .build());

KeyPair keyPair = kpg.generateKeyPair();

Load the keys

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.Entry entry = keyStore.getEntry(alias, null);
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
PublicKey publicKey = keyStore.getCertificate(alias).getPublicKey();
Share:
10,607

Related videos on Youtube

Shudy
Author by

Shudy

Enthusiastic Android developer.

Updated on September 16, 2022

Comments

  • Shudy
    Shudy over 1 year

    I need to generate a RSA 2048 Keypair, then save it, and recover it if it exists.

    At this moment, I have this:

    SecureRandom random = new SecureRandom();
    RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keySize, RSAKeyGenParameterSpec.F4);
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "SC");
    generator.initialize(spec, random);
    return generator.generateKeyPair();
    

    This works perfect, but now I tried to save and take it from Android Keystore, but I'm not achieving it. I tryed:

    String alias = "TESTINGKEY";
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null);
    if (!keyStore.containsAlias(alias)) {
        SecureRandom random = new SecureRandom();
        RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keySize, RSAKeyGenParameterSpec.F4);
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "SC");
        generator.initialize(spec, random);
        return generator.generateKeyPair();
    } else {
        Key key = keyStore.getKey(alias, null);
        if (key instanceof PrivateKey) {
            Certificate cert = keyStore.getCertificate(alias);
            return new KeyPair(cert.getPublicKey(), (PrivateKey) key);
        } else {
            return null;
        }
    }
    

    But is not working right, because at the second run of the app, the keystore don't contains the Keypair.

    In https://developer.android.com/training/articles/keystore.html?hl=es I saw that the KeyGenParameterSpec, the builder have a "alias" value, but int the RSAKeyGenParameterSpec don't.

    How can I save it?

  • pedrofb
    pedrofb over 7 years
    I was referring to the privateKey. The public key raw data is accesible using byte publickey[] = keyStore.getCertificate(alias).getPublicKey().getEncoded();. You will need to convert it to base64 to send it to server as String
  • Shudy
    Shudy over 7 years
    aaaahhh1!!!!! Perfect then! I just tryed with private one, and I supposed that will hapen with public to. I'll try again. ! Thanks a lot!
  • pedrofb
    pedrofb over 7 years
    Shudy, Could you check it?
  • Ωmega
    Ωmega about 6 years
    Does kpg.generateKeyPair() also store such generated keys to the "AndroidKeyStore" under the alias name, or the keys need to be stored by another method? If so, how? Please advise.
  • pedrofb
    pedrofb about 6 years
    @Ωmega, the keys are generated inside "AndroidKeyStore" (even using hardware support if exists) and can be recovered (private key can not be extracted) using alias
  • pedrofb
    pedrofb about 6 years
    @Ωmega, kpg.generateKeyPair(); creates a new key pair, public and private, using a random number generator, and internally it stores the keys into the keystore linked to the provided alias. You must call this method to generate the key pair the first time
  • pedrofb
    pedrofb about 6 years
    What is not working? I suggest to post a new question with the details