summaryrefslogtreecommitdiffstats
path: root/keystore/java/android/security/keystore/KeyProtection.java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore/java/android/security/keystore/KeyProtection.java')
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java135
1 files changed, 117 insertions, 18 deletions
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index b71dc82..c984439 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -33,28 +33,36 @@ import javax.crypto.Mac;
/**
* Specification of how a key or key pair is secured when imported into the
- * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
- * specifies parameters such as whether user authentication is required for using the key, what uses
- * the key is authorized for (e.g., only in {@code GCM} mode, or only for signing -- decryption not
- * permitted), the key's and validity start and end dates.
+ * <a href="{@docRoot}training/articles/keystore.html">Android Keystore system</a>. This class
+ * specifies authorized uses of the imported key, such as whether user authentication is required
+ * for using the key, what operations the key is authorized for (e.g., decryption, but not signing)
+ * and with what parameters (e.g., only with a particular padding scheme or digest), the key's and
+ * validity start and end dates. Key use authorizations expressed in this class apply only to secret
+ * keys and private keys -- public keys can be used for any supported operations.
*
- * <p>To import a key or key pair into the Android KeyStore, create an instance of this class using
+ * <p>To import a key or key pair into the Android Keystore, create an instance of this class using
* the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry}
* with the key or key pair being imported.
*
- * <p>To obtain the secret/symmetric or private key from the Android KeyStore use
+ * <p>To obtain the secret/symmetric 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 use
+ * To obtain the public key from the Android Keystore use
* {@link java.security.KeyStore#getCertificate(String)} and then
* {@link Certificate#getPublicKey()}.
*
- * <p>NOTE: The key material of keys stored in the Android KeyStore is not accessible.
+ * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
+ * Keystore, its private keys implement {@link java.security.interfaces.ECKey} or
+ * {@link java.security.interfaces.RSAKey} interfaces whereas its public keys implement
+ * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
+ * interfaces.
+ *
+ * <p>NOTE: The key material of keys stored in the Android Keystore is not accessible.
*
* <p>Instances of this class are immutable.
*
- * <p><h3>Example: Symmetric Key</h3>
- * The following example illustrates how to import an AES key into the Android KeyStore under alias
+ * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3>
+ * This example illustrates how to import an AES key into the Android KeyStore under alias
* {@code key1} authorized to be used only for encryption/decryption in GCM mode with no padding.
* The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
* <pre> {@code
@@ -71,15 +79,41 @@ import javax.crypto.Mac;
* .build());
* // Key imported, obtain a reference to it.
* SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
- * // The original key can now be thrown away.
+ * // The original key can now be discarded.
+ *
+ * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ * cipher.init(Cipher.ENCRYPT_MODE, keyStoreKey);
+ * ...
* }</pre>
*
- * <p><h3>Example: Asymmetric Key Pair</h3>
- * The following example illustrates how to import an EC key pair into the Android KeyStore under
- * alias {@code key2} authorized to be used only for signing with SHA-256 digest and only if
- * the user has been authenticated within the last ten minutes. Both the private and the public key
- * must export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509}
- * format respectively.
+ * <p><h3>Example: HMAC key for generating MACs using SHA-512</h3>
+ * This example illustrates how to import an HMAC key into the Android KeyStore under alias
+ * {@code key1} authorized to be used only for generating MACs using SHA-512 digest. The key must
+ * export its key material via {@link Key#getEncoded()} in {@code RAW} format.
+ * <pre> {@code
+ * SecretKey key = ...; // HMAC key of algorithm "HmacSHA512".
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ * "key1",
+ * new KeyStore.SecretKeyEntry(key),
+ * new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
+ * // Key imported, obtain a reference to it.
+ * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
+ * // The original key can now be discarded.
+ *
+ * Mac mac = Mac.getInstance("HmacSHA512");
+ * mac.init(keyStoreKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: EC key pair for signing/verification using ECDSA</h3>
+ * This example illustrates how to import an EC key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for signing with SHA-256 or SHA-512
+ * digests. The use of public key is unrestricted, thus permitting signature verification using any
+ * digests. Both the private and the public key must export their key material via
+ * {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format respectively.
* <pre> {@code
* PrivateKey privateKey = ...; // EC private key
* Certificate[] certChain = ...; // Certificate chain with the first certificate
@@ -91,7 +125,39 @@ import javax.crypto.Mac;
* "key2",
* new KeyStore.PrivateKeyEntry(privateKey, certChain),
* new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
+ * .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+ * .build());
+ * // Key pair imported, obtain a reference to it.
+ * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
+ * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
+ * // The original private key can now be discarded.
+ *
+ * Signature signature = Signature.getInstance("SHA256withECDSA");
+ * signature.initSign(keyStorePrivateKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: RSA key pair for signing/verification using PKCS#1 padding</h3>
+ * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for signing using the PKCS#1
+ * signature padding scheme with SHA-256 digest and only if the user has been authenticated within
+ * the last ten minutes. The use of public key is unrestricted, thus permitting signature
+ * verification using any padding schemes and digests, and without user authentication. Both the
+ * private and the public key must export their key material via {@link Key#getEncoded()} in
+ * {@code PKCS#8} and {@code X.509} format respectively.
+ * <pre> {@code
+ * PrivateKey privateKey = ...; // RSA private key
+ * Certificate[] certChain = ...; // Certificate chain with the first certificate
+ * // containing the corresponding RSA public key.
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ * "key2",
+ * new KeyStore.PrivateKeyEntry(privateKey, certChain),
+ * new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
* .setDigests(KeyProperties.DIGEST_SHA256)
+ * .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
* // Only permit this key to be used if the user
* // authenticated within the last ten minutes.
* .setUserAuthenticationRequired(true)
@@ -100,7 +166,40 @@ import javax.crypto.Mac;
* // Key pair imported, obtain a reference to it.
* PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
* PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * // The original private key can now be thrown away.
+ * // The original private key can now be discarded.
+ *
+ * Signature signature = Signature.getInstance("SHA256withRSA");
+ * signature.initSign(keyStorePrivateKey);
+ * ...
+ * }</pre>
+ *
+ * <p><h3>Example: RSA key pair for encryption/decryption using PKCS#1 padding</h3>
+ * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
+ * {@code key2} with the private key authorized to be used only for decryption using the PKCS#1
+ * encryption padding scheme. The use of public key is unrestricted, thus permitting encryption
+ * using any padding schemes and digests. Both the private and the public key must export their key
+ * material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format respectively.
+ * <pre> {@code
+ * PrivateKey privateKey = ...; // RSA private key
+ * Certificate[] certChain = ...; // Certificate chain with the first certificate
+ * // containing the corresponding RSA public key.
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ * "key2",
+ * new KeyStore.PrivateKeyEntry(privateKey, certChain),
+ * new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+ * .build());
+ * // Key pair imported, obtain a reference to it.
+ * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
+ * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
+ * // The original private key can now be discarded.
+ *
+ * Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ * cipher.init(Cipher.DECRYPT_MODE, keyStorePrivateKey);
+ * ...
* }</pre>
*/
public final class KeyProtection implements ProtectionParameter {