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