• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.security.keystore;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.app.KeyguardManager;
23 import android.hardware.fingerprint.FingerprintManager;
24 
25 import java.security.Key;
26 import java.security.Signature;
27 import java.security.KeyStore.ProtectionParameter;
28 import java.security.cert.Certificate;
29 import java.util.Date;
30 
31 import javax.crypto.Cipher;
32 import javax.crypto.Mac;
33 
34 /**
35  * Specification of how a key or key pair is secured when imported into the
36  * <a href="{@docRoot}training/articles/keystore.html">Android Keystore system</a>. This class
37  * specifies authorized uses of the imported key, such as whether user authentication is required
38  * for using the key, what operations the key is authorized for (e.g., decryption, but not signing)
39  * with what parameters (e.g., only with a particular padding scheme or digest), and the key's
40  * validity start and end dates. Key use authorizations expressed in this class apply only to secret
41  * keys and private keys -- public keys can be used for any supported operations.
42  *
43  * <p>To import a key or key pair into the Android Keystore, create an instance of this class using
44  * the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry}
45  * with the key or key pair being imported.
46  *
47  * <p>To obtain the secret/symmetric or private key from the Android Keystore use
48  * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
49  * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
50  * To obtain the public key from the Android Keystore use
51  * {@link java.security.KeyStore#getCertificate(String)} and then
52  * {@link Certificate#getPublicKey()}.
53  *
54  * <p>To help obtain algorithm-specific public parameters of key pairs stored in the Android
55  * Keystore, its private keys implement {@link java.security.interfaces.ECKey} or
56  * {@link java.security.interfaces.RSAKey} interfaces whereas its public keys implement
57  * {@link java.security.interfaces.ECPublicKey} or {@link java.security.interfaces.RSAPublicKey}
58  * interfaces.
59  *
60  * <p>NOTE: The key material of keys stored in the Android Keystore is not accessible.
61  *
62  * <p>Instances of this class are immutable.
63  *
64  * <p><h3>Known issues</h3>
65  * A known bug in Android 6.0 (API Level 23) causes user authentication-related authorizations to be
66  * enforced even for public keys. To work around this issue extract the public key material to use
67  * outside of Android Keystore. For example:
68  * <pre> {@code
69  * PublicKey unrestrictedPublicKey =
70  *         KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic(
71  *                 new X509EncodedKeySpec(publicKey.getEncoded()));
72  * }</pre>
73  *
74  * <p><h3>Example: AES key for encryption/decryption in GCM mode</h3>
75  * This example illustrates how to import an AES key into the Android KeyStore under alias
76  * {@code key1} authorized to be used only for encryption/decryption in GCM mode with no padding.
77  * The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
78  * <pre> {@code
79  * SecretKey key = ...; // AES key
80  *
81  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
82  * keyStore.load(null);
83  * keyStore.setEntry(
84  *         "key1",
85  *         new KeyStore.SecretKeyEntry(key),
86  *         new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
87  *                 .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
88  *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
89  *                 .build());
90  * // Key imported, obtain a reference to it.
91  * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
92  * // The original key can now be discarded.
93  *
94  * Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
95  * cipher.init(Cipher.ENCRYPT_MODE, keyStoreKey);
96  * ...
97  * }</pre>
98  *
99  * <p><h3>Example: HMAC key for generating MACs using SHA-512</h3>
100  * This example illustrates how to import an HMAC key into the Android KeyStore under alias
101  * {@code key1} authorized to be used only for generating MACs using SHA-512 digest. The key must
102  * export its key material via {@link Key#getEncoded()} in {@code RAW} format.
103  * <pre> {@code
104  * SecretKey key = ...; // HMAC key of algorithm "HmacSHA512".
105  *
106  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
107  * keyStore.load(null);
108  * keyStore.setEntry(
109  *         "key1",
110  *         new KeyStore.SecretKeyEntry(key),
111  *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
112  * // Key imported, obtain a reference to it.
113  * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
114  * // The original key can now be discarded.
115  *
116  * Mac mac = Mac.getInstance("HmacSHA512");
117  * mac.init(keyStoreKey);
118  * ...
119  * }</pre>
120  *
121  * <p><h3>Example: EC key pair for signing/verification using ECDSA</h3>
122  * This example illustrates how to import an EC key pair into the Android KeyStore under alias
123  * {@code key2} with the private key authorized to be used only for signing with SHA-256 or SHA-512
124  * digests. The use of the public key is unrestricted. Both the private and the public key must
125  * export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format
126  * respectively.
127  * <pre> {@code
128  * PrivateKey privateKey = ...;   // EC private key
129  * Certificate[] certChain = ...; // Certificate chain with the first certificate
130  *                                // containing the corresponding EC public key.
131  *
132  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
133  * keyStore.load(null);
134  * keyStore.setEntry(
135  *         "key2",
136  *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
137  *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
138  *                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
139  *                 .build());
140  * // Key pair imported, obtain a reference to it.
141  * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
142  * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
143  * // The original private key can now be discarded.
144  *
145  * Signature signature = Signature.getInstance("SHA256withECDSA");
146  * signature.initSign(keyStorePrivateKey);
147  * ...
148  * }</pre>
149  *
150  * <p><h3>Example: RSA key pair for signing/verification using PKCS#1 padding</h3>
151  * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
152  * {@code key2} with the private key authorized to be used only for signing using the PKCS#1
153  * signature padding scheme with SHA-256 digest and only if the user has been authenticated within
154  * the last ten minutes. The use of the public key is unrestricted (see Known Issues). Both the
155  * private and the public key must export their key material via {@link Key#getEncoded()} in
156  * {@code PKCS#8} and {@code X.509} format respectively.
157  * <pre> {@code
158  * PrivateKey privateKey = ...;   // RSA private key
159  * Certificate[] certChain = ...; // Certificate chain with the first certificate
160  *                                // containing the corresponding RSA public key.
161  *
162  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
163  * keyStore.load(null);
164  * keyStore.setEntry(
165  *         "key2",
166  *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
167  *         new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
168  *                 .setDigests(KeyProperties.DIGEST_SHA256)
169  *                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
170  *                 // Only permit this key to be used if the user
171  *                 // authenticated within the last ten minutes.
172  *                 .setUserAuthenticationRequired(true)
173  *                 .setUserAuthenticationValidityDurationSeconds(10 * 60)
174  *                 .build());
175  * // Key pair imported, obtain a reference to it.
176  * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
177  * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
178  * // The original private key can now be discarded.
179  *
180  * Signature signature = Signature.getInstance("SHA256withRSA");
181  * signature.initSign(keyStorePrivateKey);
182  * ...
183  * }</pre>
184  *
185  * <p><h3>Example: RSA key pair for encryption/decryption using PKCS#1 padding</h3>
186  * This example illustrates how to import an RSA key pair into the Android KeyStore under alias
187  * {@code key2} with the private key authorized to be used only for decryption using the PKCS#1
188  * encryption padding scheme. The use of public key is unrestricted, thus permitting encryption
189  * using any padding schemes and digests. Both the private and the public key must export their key
190  * material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} format respectively.
191  * <pre> {@code
192  * PrivateKey privateKey = ...;   // RSA private key
193  * Certificate[] certChain = ...; // Certificate chain with the first certificate
194  *                                // containing the corresponding RSA public key.
195  *
196  * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
197  * keyStore.load(null);
198  * keyStore.setEntry(
199  *         "key2",
200  *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
201  *         new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
202  *                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
203  *                 .build());
204  * // Key pair imported, obtain a reference to it.
205  * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
206  * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
207  * // The original private key can now be discarded.
208  *
209  * Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
210  * cipher.init(Cipher.DECRYPT_MODE, keyStorePrivateKey);
211  * ...
212  * }</pre>
213  */
214 public final class KeyProtection implements ProtectionParameter {
215     private final Date mKeyValidityStart;
216     private final Date mKeyValidityForOriginationEnd;
217     private final Date mKeyValidityForConsumptionEnd;
218     private final @KeyProperties.PurposeEnum int mPurposes;
219     private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
220     private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
221     private final @KeyProperties.DigestEnum String[] mDigests;
222     private final @KeyProperties.BlockModeEnum String[] mBlockModes;
223     private final boolean mRandomizedEncryptionRequired;
224     private final boolean mUserAuthenticationRequired;
225     private final int mUserAuthenticationValidityDurationSeconds;
226     private final boolean mUserAuthenticationValidWhileOnBody;
227     private final boolean mInvalidatedByBiometricEnrollment;
228 
KeyProtection( Date keyValidityStart, Date keyValidityForOriginationEnd, Date keyValidityForConsumptionEnd, @KeyProperties.PurposeEnum int purposes, @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, @KeyProperties.DigestEnum String[] digests, @KeyProperties.BlockModeEnum String[] blockModes, boolean randomizedEncryptionRequired, boolean userAuthenticationRequired, int userAuthenticationValidityDurationSeconds, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment)229     private KeyProtection(
230             Date keyValidityStart,
231             Date keyValidityForOriginationEnd,
232             Date keyValidityForConsumptionEnd,
233             @KeyProperties.PurposeEnum int purposes,
234             @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
235             @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
236             @KeyProperties.DigestEnum String[] digests,
237             @KeyProperties.BlockModeEnum String[] blockModes,
238             boolean randomizedEncryptionRequired,
239             boolean userAuthenticationRequired,
240             int userAuthenticationValidityDurationSeconds,
241             boolean userAuthenticationValidWhileOnBody,
242             boolean invalidatedByBiometricEnrollment) {
243         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
244         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
245         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
246         mPurposes = purposes;
247         mEncryptionPaddings =
248                 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
249         mSignaturePaddings =
250                 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
251         mDigests = ArrayUtils.cloneIfNotEmpty(digests);
252         mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
253         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
254         mUserAuthenticationRequired = userAuthenticationRequired;
255         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
256         mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
257         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
258     }
259 
260     /**
261      * Gets the time instant before which the key is not yet valid.
262      *
263      * @return instant or {@code null} if not restricted.
264      */
265     @Nullable
getKeyValidityStart()266     public Date getKeyValidityStart() {
267         return Utils.cloneIfNotNull(mKeyValidityStart);
268     }
269 
270     /**
271      * Gets the time instant after which the key is no long valid for decryption and verification.
272      *
273      * @return instant or {@code null} if not restricted.
274      */
275     @Nullable
getKeyValidityForConsumptionEnd()276     public Date getKeyValidityForConsumptionEnd() {
277         return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd);
278     }
279 
280     /**
281      * Gets the time instant after which the key is no long valid for encryption and signing.
282      *
283      * @return instant or {@code null} if not restricted.
284      */
285     @Nullable
getKeyValidityForOriginationEnd()286     public Date getKeyValidityForOriginationEnd() {
287         return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd);
288     }
289 
290     /**
291      * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
292      * Attempts to use the key for any other purpose will be rejected.
293      *
294      * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
295      */
getPurposes()296     public @KeyProperties.PurposeEnum int getPurposes() {
297         return mPurposes;
298     }
299 
300     /**
301      * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding},
302      * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use
303      * the key with any other padding scheme will be rejected.
304      *
305      * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
306      */
307     @NonNull
getEncryptionPaddings()308     public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
309         return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
310     }
311 
312     /**
313      * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
314      * can be used when signing/verifying. Attempts to use the key with any other padding scheme
315      * will be rejected.
316      *
317      * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
318      */
319     @NonNull
getSignaturePaddings()320     public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
321         return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
322     }
323 
324     /**
325      * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key
326      * can be used.
327      *
328      * <p>See {@link KeyProperties}.{@code DIGEST} constants.
329      *
330      * @throws IllegalStateException if this set has not been specified.
331      *
332      * @see #isDigestsSpecified()
333      */
334     @NonNull
getDigests()335     public @KeyProperties.DigestEnum String[] getDigests() {
336         if (mDigests == null) {
337             throw new IllegalStateException("Digests not specified");
338         }
339         return ArrayUtils.cloneIfNotEmpty(mDigests);
340     }
341 
342     /**
343      * Returns {@code true} if the set of digest algorithms with which the key can be used has been
344      * specified.
345      *
346      * @see #getDigests()
347      */
isDigestsSpecified()348     public boolean isDigestsSpecified() {
349         return mDigests != null;
350     }
351 
352     /**
353      * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used
354      * when encrypting/decrypting. Attempts to use the key with any other block modes will be
355      * rejected.
356      *
357      * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
358      */
359     @NonNull
getBlockModes()360     public @KeyProperties.BlockModeEnum String[] getBlockModes() {
361         return ArrayUtils.cloneIfNotEmpty(mBlockModes);
362     }
363 
364     /**
365      * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
366      * different ciphertexts for the same plaintext every time. The formal cryptographic property
367      * being required is <em>indistinguishability under chosen-plaintext attack ({@code
368      * IND-CPA})</em>. This property is important because it mitigates several classes of
369      * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
370      * given plaintext always produces the same ciphertext, an attacker may see the repeated
371      * ciphertexts and be able to deduce something about the plaintext.
372      */
isRandomizedEncryptionRequired()373     public boolean isRandomizedEncryptionRequired() {
374         return mRandomizedEncryptionRequired;
375     }
376 
377     /**
378      * Returns {@code true} if the key is authorized to be used only if the user has been
379      * authenticated.
380      *
381      * <p>This authorization applies only to secret key and private key operations. Public key
382      * operations are not restricted.
383      *
384      * @see #getUserAuthenticationValidityDurationSeconds()
385      * @see Builder#setUserAuthenticationRequired(boolean)
386      */
isUserAuthenticationRequired()387     public boolean isUserAuthenticationRequired() {
388         return mUserAuthenticationRequired;
389     }
390 
391     /**
392      * Gets the duration of time (seconds) for which this key is authorized to be used after the
393      * user is successfully authenticated. This has effect only if user authentication is required
394      * (see {@link #isUserAuthenticationRequired()}).
395      *
396      * <p>This authorization applies only to secret key and private key operations. Public key
397      * operations are not restricted.
398      *
399      * @return duration in seconds or {@code -1} if authentication is required for every use of the
400      *         key.
401      *
402      * @see #isUserAuthenticationRequired()
403      * @see Builder#setUserAuthenticationValidityDurationSeconds(int)
404      */
getUserAuthenticationValidityDurationSeconds()405     public int getUserAuthenticationValidityDurationSeconds() {
406         return mUserAuthenticationValidityDurationSeconds;
407     }
408 
409     /**
410      * Returns {@code true} if the key will be de-authorized when the device is removed from the
411      * user's body.  This option has no effect on keys that don't have an authentication validity
412      * duration, and has no effect if the device lacks an on-body sensor.
413      *
414      * <p>Authorization applies only to secret key and private key operations. Public key operations
415      * are not restricted.
416      *
417      * @see #isUserAuthenticationRequired()
418      * @see #getUserAuthenticationValidityDurationSeconds()
419      * @see Builder#setUserAuthenticationValidWhileOnBody(boolean)
420      */
isUserAuthenticationValidWhileOnBody()421     public boolean isUserAuthenticationValidWhileOnBody() {
422         return mUserAuthenticationValidWhileOnBody;
423     }
424 
425     /**
426      * Returns {@code true} if the key is irreversibly invalidated when a new fingerprint is
427      * enrolled or all enrolled fingerprints are removed. This has effect only for keys that
428      * require fingerprint user authentication for every use.
429      *
430      * @see #isUserAuthenticationRequired()
431      * @see #getUserAuthenticationValidityDurationSeconds()
432      * @see Builder#setInvalidatedByBiometricEnrollment(boolean)
433      */
isInvalidatedByBiometricEnrollment()434     public boolean isInvalidatedByBiometricEnrollment() {
435         return mInvalidatedByBiometricEnrollment;
436     }
437 
438     /**
439      * Builder of {@link KeyProtection} instances.
440      */
441     public final static class Builder {
442         private @KeyProperties.PurposeEnum int mPurposes;
443 
444         private Date mKeyValidityStart;
445         private Date mKeyValidityForOriginationEnd;
446         private Date mKeyValidityForConsumptionEnd;
447         private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
448         private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
449         private @KeyProperties.DigestEnum String[] mDigests;
450         private @KeyProperties.BlockModeEnum String[] mBlockModes;
451         private boolean mRandomizedEncryptionRequired = true;
452         private boolean mUserAuthenticationRequired;
453         private int mUserAuthenticationValidityDurationSeconds = -1;
454         private boolean mUserAuthenticationValidWhileOnBody;
455         private boolean mInvalidatedByBiometricEnrollment = true;
456 
457         /**
458          * Creates a new instance of the {@code Builder}.
459          *
460          * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
461          *        used. Attempts to use the key for any other purpose will be rejected.
462          *
463          *        <p>See {@link KeyProperties}.{@code PURPOSE} flags.
464          */
Builder(@eyProperties.PurposeEnum int purposes)465         public Builder(@KeyProperties.PurposeEnum int purposes) {
466             mPurposes = purposes;
467         }
468 
469         /**
470          * Sets the time instant before which the key is not yet valid.
471          *
472          * <p>By default, the key is valid at any instant.
473          *
474          * @see #setKeyValidityEnd(Date)
475          */
476         @NonNull
setKeyValidityStart(Date startDate)477         public Builder setKeyValidityStart(Date startDate) {
478             mKeyValidityStart = Utils.cloneIfNotNull(startDate);
479             return this;
480         }
481 
482         /**
483          * Sets the time instant after which the key is no longer valid.
484          *
485          * <p>By default, the key is valid at any instant.
486          *
487          * @see #setKeyValidityStart(Date)
488          * @see #setKeyValidityForConsumptionEnd(Date)
489          * @see #setKeyValidityForOriginationEnd(Date)
490          */
491         @NonNull
setKeyValidityEnd(Date endDate)492         public Builder setKeyValidityEnd(Date endDate) {
493             setKeyValidityForOriginationEnd(endDate);
494             setKeyValidityForConsumptionEnd(endDate);
495             return this;
496         }
497 
498         /**
499          * Sets the time instant after which the key is no longer valid for encryption and signing.
500          *
501          * <p>By default, the key is valid at any instant.
502          *
503          * @see #setKeyValidityForConsumptionEnd(Date)
504          */
505         @NonNull
setKeyValidityForOriginationEnd(Date endDate)506         public Builder setKeyValidityForOriginationEnd(Date endDate) {
507             mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate);
508             return this;
509         }
510 
511         /**
512          * Sets the time instant after which the key is no longer valid for decryption and
513          * verification.
514          *
515          * <p>By default, the key is valid at any instant.
516          *
517          * @see #setKeyValidityForOriginationEnd(Date)
518          */
519         @NonNull
setKeyValidityForConsumptionEnd(Date endDate)520         public Builder setKeyValidityForConsumptionEnd(Date endDate) {
521             mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate);
522             return this;
523         }
524 
525         /**
526          * Sets the set of padding schemes (e.g., {@code OAEPPadding}, {@code PKCS7Padding},
527          * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to
528          * use the key with any other padding scheme will be rejected.
529          *
530          * <p>This must be specified for keys which are used for encryption/decryption.
531          *
532          * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
533          * is usually necessary to authorize the use of no/any padding
534          * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
535          * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
536          * required by some cipher suites, and some stacks request decryption using no padding
537          * whereas others request PKCS#1 padding.
538          *
539          * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
540          */
541         @NonNull
setEncryptionPaddings( @eyProperties.EncryptionPaddingEnum String... paddings)542         public Builder setEncryptionPaddings(
543                 @KeyProperties.EncryptionPaddingEnum String... paddings) {
544             mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
545             return this;
546         }
547 
548         /**
549          * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
550          * can be used when signing/verifying. Attempts to use the key with any other padding scheme
551          * will be rejected.
552          *
553          * <p>This must be specified for RSA keys which are used for signing/verification.
554          *
555          * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
556          */
557         @NonNull
setSignaturePaddings( @eyProperties.SignaturePaddingEnum String... paddings)558         public Builder setSignaturePaddings(
559                 @KeyProperties.SignaturePaddingEnum String... paddings) {
560             mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
561             return this;
562         }
563 
564         /**
565          * Sets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the
566          * key can be used. Attempts to use the key with any other digest algorithm will be
567          * rejected.
568          *
569          * <p>This must be specified for signing/verification keys and RSA encryption/decryption
570          * keys used with RSA OAEP padding scheme because these operations involve a digest. For
571          * HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()} (e.g.,
572          * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized
573          * for more than one digest.
574          *
575          * <p>For private keys used for TLS/SSL client or server authentication it is usually
576          * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is
577          * because TLS/SSL stacks typically generate the necessary digest(s) themselves and then use
578          * a private key to sign it.
579          *
580          * <p>See {@link KeyProperties}.{@code DIGEST} constants.
581          */
582         @NonNull
setDigests(@eyProperties.DigestEnum String... digests)583         public Builder setDigests(@KeyProperties.DigestEnum String... digests) {
584             mDigests = ArrayUtils.cloneIfNotEmpty(digests);
585             return this;
586         }
587 
588         /**
589          * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be
590          * used when encrypting/decrypting. Attempts to use the key with any other block modes will
591          * be rejected.
592          *
593          * <p>This must be specified for symmetric encryption/decryption keys.
594          *
595          * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
596          */
597         @NonNull
setBlockModes(@eyProperties.BlockModeEnum String... blockModes)598         public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) {
599             mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
600             return this;
601         }
602 
603         /**
604          * Sets whether encryption using this key must be sufficiently randomized to produce
605          * different ciphertexts for the same plaintext every time. The formal cryptographic
606          * property being required is <em>indistinguishability under chosen-plaintext attack
607          * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
608          * of weaknesses due to which ciphertext may leak information about plaintext. For example,
609          * if a given plaintext always produces the same ciphertext, an attacker may see the
610          * repeated ciphertexts and be able to deduce something about the plaintext.
611          *
612          * <p>By default, {@code IND-CPA} is required.
613          *
614          * <p>When {@code IND-CPA} is required:
615          * <ul>
616          * <li>transformation which do not offer {@code IND-CPA}, such as symmetric ciphers using
617          * {@code ECB} mode or RSA encryption without padding, are prohibited;</li>
618          * <li>in transformations which use an IV, such as symmetric ciphers in {@code GCM},
619          * {@code CBC}, and {@code CTR} block modes, caller-provided IVs are rejected when
620          * encrypting, to ensure that only random IVs are used.</li>
621          *
622          * <p>Before disabling this requirement, consider the following approaches instead:
623          * <ul>
624          * <li>If you are generating a random IV for encryption and then initializing a {@code}
625          * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
626          * instead. This will occur if the {@code Cipher} is initialized for encryption without an
627          * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
628          * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
629          * random, such as the name of the file being encrypted, or transaction ID, or password,
630          * or a device identifier), consider changing your design to use a random IV which will then
631          * be provided in addition to the ciphertext to the entities which need to decrypt the
632          * ciphertext.</li>
633          * <li>If you are using RSA encryption without padding, consider switching to padding
634          * schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
635          * </ul>
636          */
637         @NonNull
setRandomizedEncryptionRequired(boolean required)638         public Builder setRandomizedEncryptionRequired(boolean required) {
639             mRandomizedEncryptionRequired = required;
640             return this;
641         }
642 
643         /**
644          * Sets whether this key is authorized to be used only if the user has been authenticated.
645          *
646          * <p>By default, the key is authorized to be used regardless of whether the user has been
647          * authenticated.
648          *
649          * <p>When user authentication is required:
650          * <ul>
651          * <li>The key can only be import if secure lock screen is set up (see
652          * {@link KeyguardManager#isDeviceSecure()}). Additionally, if the key requires that user
653          * authentication takes place for every use of the key (see
654          * {@link #setUserAuthenticationValidityDurationSeconds(int)}), at least one fingerprint
655          * must be enrolled (see {@link FingerprintManager#hasEnrolledFingerprints()}).</li>
656          * <li>The use of the key must be authorized by the user by authenticating to this Android
657          * device using a subset of their secure lock screen credentials such as
658          * password/PIN/pattern or fingerprint.
659          * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
660          * information</a>.
661          * <li>The key will become <em>irreversibly invalidated</em> once the secure lock screen is
662          * disabled (reconfigured to None, Swipe or other mode which does not authenticate the user)
663          * or when the secure lock screen is forcibly reset (e.g., by a Device Administrator).
664          * Additionally, if the key requires that user authentication takes place for every use of
665          * the key, it is also irreversibly invalidated once a new fingerprint is enrolled or once\
666          * no more fingerprints are enrolled, unless {@link
667          * #setInvalidatedByBiometricEnrollment(boolean)} is used to allow validity after
668          * enrollment. Attempts to initialize cryptographic operations using such keys will throw
669          * {@link KeyPermanentlyInvalidatedException}.</li> </ul>
670          *
671          * <p>This authorization applies only to secret key and private key operations. Public key
672          * operations are not restricted.
673          *
674          * @see #setUserAuthenticationValidityDurationSeconds(int)
675          * @see KeyguardManager#isDeviceSecure()
676          * @see FingerprintManager#hasEnrolledFingerprints()
677          */
678         @NonNull
setUserAuthenticationRequired(boolean required)679         public Builder setUserAuthenticationRequired(boolean required) {
680             mUserAuthenticationRequired = required;
681             return this;
682         }
683 
684         /**
685          * Sets the duration of time (seconds) for which this key is authorized to be used after the
686          * user is successfully authenticated. This has effect if the key requires user
687          * authentication for its use (see {@link #setUserAuthenticationRequired(boolean)}).
688          *
689          * <p>By default, if user authentication is required, it must take place for every use of
690          * the key.
691          *
692          * <p>Cryptographic operations involving keys which require user authentication to take
693          * place for every operation can only use fingerprint authentication. This is achieved by
694          * initializing a cryptographic operation ({@link Signature}, {@link Cipher}, {@link Mac})
695          * with the key, wrapping it into a {@link FingerprintManager.CryptoObject}, invoking
696          * {@code FingerprintManager.authenticate} with {@code CryptoObject}, and proceeding with
697          * the cryptographic operation only if the authentication flow succeeds.
698          *
699          * <p>Cryptographic operations involving keys which are authorized to be used for a duration
700          * of time after a successful user authentication event can only use secure lock screen
701          * authentication. These cryptographic operations will throw
702          * {@link UserNotAuthenticatedException} during initialization if the user needs to be
703          * authenticated to proceed. This situation can be resolved by the user unlocking the secure
704          * lock screen of the Android or by going through the confirm credential flow initiated by
705          * {@link KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence)}.
706          * Once resolved, initializing a new cryptographic operation using this key (or any other
707          * key which is authorized to be used for a fixed duration of time after user
708          * authentication) should succeed provided the user authentication flow completed
709          * successfully.
710          *
711          * @param seconds duration in seconds or {@code -1} if user authentication must take place
712          *        for every use of the key.
713          *
714          * @see #setUserAuthenticationRequired(boolean)
715          * @see FingerprintManager
716          * @see FingerprintManager.CryptoObject
717          * @see KeyguardManager
718          */
719         @NonNull
setUserAuthenticationValidityDurationSeconds( @ntRangefrom = -1) int seconds)720         public Builder setUserAuthenticationValidityDurationSeconds(
721                 @IntRange(from = -1) int seconds) {
722             if (seconds < -1) {
723                 throw new IllegalArgumentException("seconds must be -1 or larger");
724             }
725             mUserAuthenticationValidityDurationSeconds = seconds;
726             return this;
727         }
728 
729         /**
730          * Sets whether the key will remain authorized only until the device is removed from the
731          * user's body up to the limit of the authentication validity period (see
732          * {@link #setUserAuthenticationValidityDurationSeconds} and
733          * {@link #setUserAuthenticationRequired}). Once the device has been removed from the
734          * user's body, the key will be considered unauthorized and the user will need to
735          * re-authenticate to use it. For keys without an authentication validity period this
736          * parameter has no effect.
737          *
738          * <p>Similarly, on devices that do not have an on-body sensor, this parameter will have no
739          * effect; the device will always be considered to be "on-body" and the key will therefore
740          * remain authorized until the validity period ends.
741          *
742          * @param remainsValid if {@code true}, and if the device supports on-body detection, key
743          * will be invalidated when the device is removed from the user's body or when the
744          * authentication validity expires, whichever occurs first.
745          */
746         @NonNull
setUserAuthenticationValidWhileOnBody(boolean remainsValid)747         public Builder setUserAuthenticationValidWhileOnBody(boolean remainsValid) {
748             mUserAuthenticationValidWhileOnBody = remainsValid;
749             return this;
750         }
751 
752         /**
753          * Sets whether this key should be invalidated on fingerprint enrollment.  This
754          * applies only to keys which require user authentication (see {@link
755          * #setUserAuthenticationRequired(boolean)}) and if no positive validity duration has been
756          * set (see {@link #setUserAuthenticationValidityDurationSeconds(int)}, meaning the key is
757          * valid for fingerprint authentication only.
758          *
759          * <p>By default, {@code invalidateKey} is {@code true}, so keys that are valid for
760          * fingerprint authentication only are <em>irreversibly invalidated</em> when a new
761          * fingerprint is enrolled, or when all existing fingerprints are deleted.  That may be
762          * changed by calling this method with {@code invalidateKey} set to {@code false}.
763          *
764          * <p>Invalidating keys on enrollment of a new finger or unenrollment of all fingers
765          * improves security by ensuring that an unauthorized person who obtains the password can't
766          * gain the use of fingerprint-authenticated keys by enrolling their own finger.  However,
767          * invalidating keys makes key-dependent operations impossible, requiring some fallback
768          * procedure to authenticate the user and set up a new key.
769          */
770         @NonNull
setInvalidatedByBiometricEnrollment(boolean invalidateKey)771         public Builder setInvalidatedByBiometricEnrollment(boolean invalidateKey) {
772             mInvalidatedByBiometricEnrollment = invalidateKey;
773             return this;
774         }
775 
776         /**
777          * Builds an instance of {@link KeyProtection}.
778          *
779          * @throws IllegalArgumentException if a required field is missing
780          */
781         @NonNull
build()782         public KeyProtection build() {
783             return new KeyProtection(
784                     mKeyValidityStart,
785                     mKeyValidityForOriginationEnd,
786                     mKeyValidityForConsumptionEnd,
787                     mPurposes,
788                     mEncryptionPaddings,
789                     mSignaturePaddings,
790                     mDigests,
791                     mBlockModes,
792                     mRandomizedEncryptionRequired,
793                     mUserAuthenticationRequired,
794                     mUserAuthenticationValidityDurationSeconds,
795                     mUserAuthenticationValidWhileOnBody,
796                     mInvalidatedByBiometricEnrollment);
797         }
798     }
799 }
800