KeyGenParameterSpec Class
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
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
- 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 |
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 |
Handle |
The handle to the underlying Android instance. (Inherited from Object) |
IsDevicePropertiesAttestationIncluded |
Returns |
IsDigestsSpecified |
Returns |
IsInvalidatedByBiometricEnrollment |
Returns |
IsRandomizedEncryptionRequired |
Returns |
IsStrongBoxBacked |
Returns |
IsUnlockedDeviceRequired |
Returns |
IsUserAuthenticationRequired |
Returns |
IsUserAuthenticationValidWhileOnBody |
Returns |
IsUserConfirmationRequired |
Returns |
IsUserPresenceRequired |
Returns |
JniIdentityHashCode | (Inherited from Object) |
JniPeerMembers | |
KeySize |
Returns the requested key size. |
KeystoreAlias |
Returns the alias that will be used in the |
KeyValidityForConsumptionEnd |
Returns the time instant after which the key is no longer valid for decryption and
verification or |
KeyValidityForOriginationEnd |
Returns the time instant after which the key is no longer valid for encryption and signing
or |
KeyValidityStart |
Returns the time instant before which the key is not yet valid or |
MaxUsageCount |
Returns the maximum number of times the limited use key is allowed to be used or
|
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) |