diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index f42d750818993..f9f678895673e 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -40,9 +40,9 @@ import javax.security.auth.x500.X500Principal; * {@link 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) 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. + * 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 {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the @@ -90,13 +90,22 @@ import javax.security.auth.x500.X500Principal; * *

Instances of this class are immutable. * + *

Known issues

+ * 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()));
+ * }
+ * *

Example: NIST P-256 EC key pair for signing/verification using ECDSA

* 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. + * 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");
@@ -128,8 +137,7 @@ import javax.security.auth.x500.X500Principal;
  * 

Example: RSA key pair for signing/verification using RSA-PSS

* 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. + * 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");
@@ -155,8 +163,8 @@ import javax.security.auth.x500.X500Principal;
  * 

Example: RSA key pair for encryption/decryption using RSA OAEP

* 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. + * 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");
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index c98443978105e..45941bafedfe7 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -36,7 +36,7 @@ import javax.crypto.Mac;
  * Android Keystore system. 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
+ * 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 this class apply only to secret
  * keys and private keys -- public keys can be used for any supported operations.
  *
@@ -61,6 +61,16 @@ import javax.crypto.Mac;
  *
  * 

Instances of this class are immutable. * + *

Known issues

+ * 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()));
+ * }
+ * *

Example: AES key for encryption/decryption in GCM mode

* 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. @@ -111,9 +121,9 @@ import javax.crypto.Mac; *

Example: EC key pair for signing/verification using ECDSA

* 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. + * digests. The use of the public key is unrestricted. 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. *
 {@code
  * PrivateKey privateKey = ...;   // EC private key
  * Certificate[] certChain = ...; // Certificate chain with the first certificate
@@ -141,8 +151,7 @@ import javax.crypto.Mac;
  * 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
+ * the last ten minutes. The use of the public key is unrestricted (see Known Issues). 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.
  * 
 {@code