Share via


KeyGenParameterSpec Class

Definition

AlgorithmParameterSpec for initializing a KeyPairGenerator or a KeyGenerator of the Android Keystore system.

[Android.Runtime.Register("android/security/keystore/KeyGenParameterSpec", ApiSince=23, DoNotGenerateAcw=true)]
public sealed class KeyGenParameterSpec : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.Security.Spec.IAlgorithmParameterSpec
[<Android.Runtime.Register("android/security/keystore/KeyGenParameterSpec", ApiSince=23, DoNotGenerateAcw=true)>]
type KeyGenParameterSpec = class
    inherit Object
    interface IAlgorithmParameterSpec
    interface IJavaObject
    interface IDisposable
    interface IJavaPeerable
Inheritance
KeyGenParameterSpec
Attributes
Implements

Remarks

AlgorithmParameterSpec for initializing a KeyPairGenerator or a KeyGenerator of the Android Keystore system. The spec determines authorized uses of the key, such as whether user authentication is required for using the key, what operations are authorized (e.g., signing, but not decryption), with what parameters (e.g., only with a particular padding scheme or digest), and the key's validity start and end dates. Key use authorizations expressed in the spec apply only to secret keys and private keys -- public keys can be used for any supported operations.

To generate an asymmetric key pair or a symmetric key, create an instance of this class using the Builder, initialize a KeyPairGenerator or a KeyGenerator of the desired key type (e.g., EC or AES -- see KeyProperties.KEY_ALGORITHM constants) from the AndroidKeyStore provider with the KeyGenParameterSpec instance, and then generate a key or key pair using KeyGenerator#generateKey() or KeyPairGenerator#generateKeyPair().

The generated key pair or key will be returned by the generator and also stored in the Android Keystore under the alias specified in this spec. To obtain the secret or private key from the Android Keystore use java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null) or java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null). To obtain the public key from the Android Keystore use java.security.KeyStore#getCertificate(String) and then Certificate#getPublicKey().

To help obtain algorithm-specific public parameters of key pairs stored in the Android Keystore, generated private keys implement java.security.interfaces.ECKey or java.security.interfaces.RSAKey interfaces whereas public keys implement java.security.interfaces.ECPublicKey or java.security.interfaces.RSAPublicKey interfaces.

For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in the Android Keystore. This is because the java.security.KeyStore abstraction does not support storing key pairs without a certificate. The subject, serial number, and validity dates of the certificate can be customized in this spec. The self-signed certificate may be replaced at a later time by a certificate signed by a Certificate Authority (CA).

NOTE: If a private key is not authorized to sign the self-signed certificate, then the certificate will be created with an invalid signature which will not verify. Such a certificate is still useful because it provides access to the public key. To generate a valid signature for the certificate the key needs to be authorized for all of the following: <ul> <li>KeyProperties#PURPOSE_SIGN,</li> <li>operation without requiring the user to be authenticated (see Builder#setUserAuthenticationRequired(boolean)),</li> <li>signing/origination at this moment in time (see Builder#setKeyValidityStart(Date) and Builder#setKeyValidityForOriginationEnd(Date)),</li> <li>suitable digest,</li> <li>(RSA keys only) padding scheme KeyProperties#SIGNATURE_PADDING_RSA_PKCS1.</li> </ul>

NOTE: The key material of the generated symmetric and private keys is not accessible. The key material of the public keys is accessible.

Instances of this class are immutable.

<h3>Known issues</h3> A known bug in Android 6.0 (API Level 23) causes user authentication-related authorizations to be enforced even for public keys. To work around this issue extract the public key material to use outside of Android Keystore. For example:

{@code
            PublicKey unrestrictedPublicKey =
                    KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic(
                            new X509EncodedKeySpec(publicKey.getEncoded()));
            }

<h3>Example: NIST P-256 EC key pair for signing/verification using ECDSA</h3> This example illustrates how to generate a NIST P-256 (aka secp256r1 aka prime256v1) EC key pair in the Android KeyStore system under alias key1 where the private key is authorized to be used only for signing using SHA-256, SHA-384, or SHA-512 digest and only if the user has been authenticated within the last five minutes. The use of the public key is unrestricted (See Known Issues).

{@code
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
            keyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(
                            "key1",
                            KeyProperties.PURPOSE_SIGN)
                            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                            .setDigests(KeyProperties.DIGEST_SHA256,
                                    KeyProperties.DIGEST_SHA384,
                                    KeyProperties.DIGEST_SHA512)
                            // Only permit the private key to be used if the user authenticated
                            // within the last five minutes.
                            .setUserAuthenticationRequired(true)
                            .setUserAuthenticationValidityDurationSeconds(5 * 60)
                            .build());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            Signature signature = Signature.getInstance("SHA256withECDSA");
            signature.initSign(keyPair.getPrivate());
            ...

            // The key pair can also be obtained from the Android Keystore any time as follows:
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
            PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
            }

<h3>Example: RSA key pair for signing/verification using RSA-PSS</h3> This example illustrates how to generate an RSA key pair in the Android KeyStore system under alias key1 authorized to be used only for signing using the RSA-PSS signature padding scheme with SHA-256 or SHA-512 digests. The use of the public key is unrestricted.

{@code
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
            keyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(
                            "key1",
                            KeyProperties.PURPOSE_SIGN)
                            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                            .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
                            .build());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            Signature signature = Signature.getInstance("SHA256withRSA/PSS");
            signature.initSign(keyPair.getPrivate());
            ...

            // The key pair can also be obtained from the Android Keystore any time as follows:
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
            PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
            }

<h3>Example: RSA key pair for encryption/decryption using RSA OAEP</h3> This example illustrates how to generate an RSA key pair in the Android KeyStore system under alias key1 where the private key is authorized to be used only for decryption using RSA OAEP encryption padding scheme with SHA-256 or SHA-512 digests. The use of the public key is unrestricted.

{@code
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
            keyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(
                            "key1",
                            KeyProperties.PURPOSE_DECRYPT)
                            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                            .build());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
            ...

            // The key pair can also be obtained from the Android Keystore any time as follows:
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
            PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
            }

<h3>Example: AES key for encryption/decryption in GCM mode</h3> The following example illustrates how to generate an AES key in the Android KeyStore system under alias key2 authorized to be used only for encryption/decryption in GCM mode with no padding.

{@code
            KeyGenerator keyGenerator = KeyGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            keyGenerator.init(
                    new KeyGenParameterSpec.Builder("key2",
                            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                            .build());
            SecretKey key = keyGenerator.generateKey();

            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            ...

            // The key can also be obtained from the Android Keystore any time as follows:
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            key = (SecretKey) keyStore.getKey("key2", null);
            }

<h3>Example: HMAC key for generating a MAC using SHA-256</h3> This example illustrates how to generate an HMAC key in the Android KeyStore system under alias key2 authorized to be used only for generating an HMAC using SHA-256.

{@code
            KeyGenerator keyGenerator = KeyGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
            keyGenerator.init(
                    new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build());
            SecretKey key = keyGenerator.generateKey();
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(key);
            ...

            // The key can also be obtained from the Android Keystore any time as follows:
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            key = (SecretKey) keyStore.getKey("key2", null);
            }

<h3 id="example:ecdh">Example: EC key for ECDH key agreement</h3> This example illustrates how to generate an elliptic curve key pair, used to establish a shared secret with another party using ECDH key agreement.

{@code
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
            keyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(
                        "eckeypair",
                        KeyProperties.PURPOSE_AGREE_KEY)
                        .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                        .build());
            KeyPair myKeyPair = keyPairGenerator.generateKeyPair();

            // Exchange public keys with server. A new ephemeral key MUST be used for every message.
            PublicKey serverEphemeralPublicKey; // Ephemeral key received from server.

            // Create a shared secret based on our private key and the other party's public key.
            KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH", "AndroidKeyStore");
            keyAgreement.init(myKeyPair.getPrivate());
            keyAgreement.doPhase(serverEphemeralPublicKey, true);
            byte[] sharedSecret = keyAgreement.generateSecret();

            // sharedSecret cannot safely be used as a key yet. We must run it through a key derivation
            // function with some other data: "salt" and "info". Salt is an optional random value,
            // omitted in this example. It's good practice to include both public keys and any other
            // key negotiation data in info. Here we use the public keys and a label that indicates
            // messages encrypted with this key are coming from the server.
            byte[] salt = {};
            ByteArrayOutputStream info = new ByteArrayOutputStream();
            info.write("ECDH secp256r1 AES-256-GCM-SIV\0".getBytes(StandardCharsets.UTF_8));
            info.write(myKeyPair.getPublic().getEncoded());
            info.write(serverEphemeralPublicKey.getEncoded());

            // This example uses the Tink library and the HKDF key derivation function.
            AesGcmSiv key = new AesGcmSiv(Hkdf.computeHkdf(
                    "HMACSHA256", sharedSecret, salt, info.toByteArray(), 32));
            byte[] associatedData = {};
            return key.decrypt(ciphertext, associatedData);
            }

Java documentation for android.security.keystore.KeyGenParameterSpec.

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

Properties

AlgorithmParameterSpec

Returns the key algorithm-specific AlgorithmParameterSpec that will be used for creation of the key or null if algorithm-specific defaults should be used.

AttestKeyAlias

Returns the alias of the attestation key that will be used to sign the attestation certificate of the generated key.

CertificateNotAfter

Returns the end date to be used on the X.

CertificateNotBefore

Returns the start date to be used on the X.

CertificateSerialNumber

Returns the serial number to be used on the X.

CertificateSubject

Returns the subject distinguished name to be used on the X.

Class

Returns the runtime class of this Object.

(Inherited from Object)
Handle

The handle to the underlying Android instance.

(Inherited from Object)
IsDevicePropertiesAttestationIncluded

Returns true if attestation for the base device properties (Build#BRAND, Build#DEVICE, Build#MANUFACTURER, Build#MODEL, Build#PRODUCT) was requested to be added in the attestation certificate for the generated key.

IsDigestsSpecified

Returns true if the set of digest algorithms with which the key can be used has been specified.

IsInvalidatedByBiometricEnrollment

Returns true if the key is irreversibly invalidated when a new biometric is enrolled or all enrolled biometrics are removed.

IsRandomizedEncryptionRequired

Returns true if encryption using this key must be sufficiently randomized to produce different ciphertexts for the same plaintext every time.

IsStrongBoxBacked

Returns true if the key is protected by a Strongbox security chip.

IsUnlockedDeviceRequired

Returns true if the screen must be unlocked for this key to be used for decryption or signing.

IsUserAuthenticationRequired

Returns true if the key is authorized to be used only if the user has been authenticated.

IsUserAuthenticationValidWhileOnBody

Returns true if the key will remain authorized only until the device is removed from the user's body, up to the validity duration.

IsUserConfirmationRequired

Returns true if the key is authorized to be used only for messages confirmed by the user.

IsUserPresenceRequired

Returns true if the key is authorized to be used only if a test of user presence has been performed between the Signature.initSign() and Signature.sign() calls.

JniIdentityHashCode (Inherited from Object)
JniPeerMembers
KeySize

Returns the requested key size.

KeystoreAlias

Returns the alias that will be used in the java.security.KeyStore in conjunction with the AndroidKeyStore.

KeyValidityForConsumptionEnd

Returns the time instant after which the key is no longer valid for decryption and verification or null if not restricted.

KeyValidityForOriginationEnd

Returns the time instant after which the key is no longer valid for encryption and signing or null if not restricted.

KeyValidityStart

Returns the time instant before which the key is not yet valid or null if not restricted.

MaxUsageCount

Returns the maximum number of times the limited use key is allowed to be used or KeyProperties#UNRESTRICTED_USAGE_COUNT if there’s no restriction on the number of times the key can be used.

PeerReference (Inherited from Object)
Purposes

Returns the set of purposes (e.

ThresholdClass

This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.

(Inherited from Object)
ThresholdType

This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.

(Inherited from Object)
UserAuthenticationType

Gets the modes of authentication that can authorize use of this key.

UserAuthenticationValidityDurationSeconds

Gets the duration of time (seconds) for which this key is authorized to be used after the user is successfully authenticated.

Methods

Clone()

Creates and returns a copy of this object.

(Inherited from Object)
Dispose() (Inherited from Object)
Dispose(Boolean) (Inherited from Object)
Equals(Object)

Indicates whether some other object is "equal to" this one.

(Inherited from Object)
GetAttestationChallenge()

Returns the attestation challenge value that will be placed in attestation certificate for this key pair.

GetBlockModes()

Gets the set of block modes (e.

GetDigests()

Returns the set of digest algorithms (e.

GetEncryptionPaddings()

Returns the set of padding schemes (e.

GetHashCode()

Returns a hash code value for the object.

(Inherited from Object)
GetSignaturePaddings()

Gets the set of padding schemes (e.

JavaFinalize()

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

(Inherited from Object)
Notify()

Wakes up a single thread that is waiting on this object's monitor.

(Inherited from Object)
NotifyAll()

Wakes up all threads that are waiting on this object's monitor.

(Inherited from Object)
SetHandle(IntPtr, JniHandleOwnership)

Sets the Handle property.

(Inherited from Object)
ToArray<T>() (Inherited from Object)
ToString()

Returns a string representation of the object.

(Inherited from Object)
UnregisterFromRuntime() (Inherited from Object)
Wait()

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>.

(Inherited from Object)
Wait(Int64, Int32)

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed.

(Inherited from Object)
Wait(Int64)

Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed.

(Inherited from Object)

Explicit Interface Implementations

IJavaPeerable.Disposed() (Inherited from Object)
IJavaPeerable.DisposeUnlessReferenced() (Inherited from Object)
IJavaPeerable.Finalized() (Inherited from Object)
IJavaPeerable.JniManagedPeerState (Inherited from Object)
IJavaPeerable.SetJniIdentityHashCode(Int32) (Inherited from Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) (Inherited from Object)
IJavaPeerable.SetPeerReference(JniObjectReference) (Inherited from Object)

Extension Methods

JavaCast<TResult>(IJavaObject)

Performs an Android runtime-checked type conversion.

JavaCast<TResult>(IJavaObject)
GetJniTypeName(IJavaPeerable)

Applies to