summaryrefslogtreecommitdiffstats
path: root/keystore/java/android/security/keystore/KeyGenParameterSpec.java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore/java/android/security/keystore/KeyGenParameterSpec.java')
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java130
1 files changed, 110 insertions, 20 deletions
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 7605231..f42d750 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -38,27 +38,35 @@ import javax.security.auth.x500.X500Principal;
/**
* {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a
* {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore
- * system</a>. The spec determines whether user authentication is required for using the key, what
- * uses the key is authorized for (e.g., only for signing -- decryption not permitted), the key's
- * validity start and end dates.
+ * system</a>. 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) and with what parameters (e.g., only with a particular padding scheme or digest), 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.
*
* <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using
* the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the
* desired key type (e.g., {@code EC} or {@code AES} -- see
* {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider
- * with the {@code KeyPairGeneratorSpec} instance, and then generate a key or key pair using
- * {@link KeyPairGenerator#generateKeyPair()}.
+ * with the {@code KeyGenParameterSpec} instance, and then generate a key or key pair using
+ * {@link KeyGenerator#generateKey()} or {@link KeyPairGenerator#generateKeyPair()}.
*
* <p>The generated key pair or key will be returned by the generator and also stored in the Android
- * Keystore system under the alias specified in this spec. To obtain the secret or private key from
- * the Android KeyStore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
+ * Keystore under the alias specified in this spec. To obtain the secret or private key from the
+ * Android Keystore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
* or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- * To obtain the public key from the Android Keystore system use
+ * To obtain the public key from the Android Keystore use
* {@link java.security.KeyStore#getCertificate(String)} and then
* {@link Certificate#getPublicKey()}.
*
+ * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
+ * Keystore, generated private keys implement {@link java.security.interfaces.ECKey} or
+ * {@link java.security.interfaces.RSAKey} interfaces whereas public keys implement
+ * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
+ * interfaces.
+ *
* <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in
- * the Android KeyStore. This is because the {@link java.security.KeyStore} abstraction does not
+ * the Android Keystore. This is because the {@link 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).
@@ -82,27 +90,60 @@ import javax.security.auth.x500.X500Principal;
*
* <p>Instances of this class are immutable.
*
- * <p><h3>Example: Asymmetric key pair</h3>
- * The following example illustrates how to generate an EC key pair in the Android KeyStore system
- * under alias {@code key1} 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.
+ * <p><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 {@code 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 public key is unrestricted, thus
+ * permitting signature verification using any padding schemes and digests, and without user
+ * authentication.
* <pre> {@code
* KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
- * KeyProperties.KEY_ALGORITHM_EC,
- * "AndroidKeyStore");
+ * KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
* keyPairGenerator.initialize(
* new KeyGenParameterSpec.Builder(
* "key1",
- * KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+ * KeyProperties.PURPOSE_SIGN)
+ * .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
* .setDigests(KeyProperties.DIGEST_SHA256,
* KeyProperties.DIGEST_SHA384,
* KeyProperties.DIGEST_SHA512)
- * // Only permit this key to be used if the user authenticated
+ * // 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();
+ * }</pre>
+ *
+ * <p><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 {@code 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 public key is unrestricted, thus permitting
+ * signature verification using any padding schemes and digests.
+ * <pre> {@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");
@@ -111,14 +152,40 @@ import javax.security.auth.x500.X500Principal;
* PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
* }</pre>
*
- * <p><h3>Example: Symmetric key</h3>
+ * <p><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 {@code 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 public key is
+ * unrestricted, thus permitting encryption using any padding schemes and digests.
+ * <pre> {@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();
+ * }</pre>
+ *
+ * <p><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 {@code key2} authorized to be used only for encryption/decryption in GCM mode with no
* padding.
* <pre> {@code
* KeyGenerator keyGenerator = KeyGenerator.getInstance(
- * KeyProperties.KEY_ALGORITHM_AES,
- * "AndroidKeyStore");
+ * KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
* keyGenerator.initialize(
* new KeyGenParameterSpec.Builder("key2",
* KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
@@ -127,6 +194,29 @@ import javax.security.auth.x500.X500Principal;
* .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);
+ * }</pre>
+ *
+ * <p><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
+ * {@code key2} authorized to be used only for generating an HMAC using SHA-256.
+ * <pre> {@code
+ * KeyGenerator keyGenerator = KeyGenerator.getInstance(
+ * KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
+ * keyGenerator.initialize(
+ * 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);