KeyGenParameterSpec.java revision a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213
13f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin/* 23f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Copyright (C) 2012 The Android Open Source Project 33f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 43f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Licensed under the Apache License, Version 2.0 (the "License"); 53f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * you may not use this file except in compliance with the License. 63f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * You may obtain a copy of the License at 73f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 83f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * http://www.apache.org/licenses/LICENSE-2.0 93f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Unless required by applicable law or agreed to in writing, software 113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * distributed under the License is distributed on an "AS IS" BASIS, 123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * See the License for the specific language governing permissions and 143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * limitations under the License. 153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpackage android.security.keystore; 183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.IntRange; 203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.NonNull; 213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.annotation.Nullable; 223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.text.TextUtils; 233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.math.BigInteger; 253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.KeyPairGenerator; 263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.cert.Certificate; 273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.security.spec.AlgorithmParameterSpec; 283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport java.util.Date; 293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.Cipher; 313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.crypto.KeyGenerator; 323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport javax.security.auth.x500.X500Principal; 333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin/** 353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a 363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore 373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * system</a>. The spec determines whether user authentication is required for using the key, what 3896481c3ddc6c58cfcad2a5cb9325ee2b24b0c540Alex Klyubin * uses the key is authorized for (e.g., only for signing -- decryption not permitted), the key's 3996481c3ddc6c58cfcad2a5cb9325ee2b24b0c540Alex Klyubin * validity start and end dates. 403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using 423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the 433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * desired key type (e.g., {@code EC} or {@code AES} -- see 443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider 453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * with the {@code KeyPairGeneratorSpec} instance, and then generate a key or key pair using 463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyPairGenerator#generateKeyPair()}. 473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>The generated key pair or key will be returned by the generator and also stored in the Android 493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Keystore system under the alias specified in this spec. To obtain the secret or private key from 503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the Android KeyStore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} 513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}. 523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * To obtain the public key from the Android Keystore system use 533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore#getCertificate(String)} and then 543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link Certificate#getPublicKey()}. 553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in 573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the Android KeyStore. This is because the {@link java.security.KeyStore} abstraction does not 583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * support storing key pairs without a certificate. The subject, serial number, and validity dates 593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * of the certificate can be customized in this spec. The self-signed certificate may be replaced at 603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * a later time by a certificate signed by a Certificate Authority (CA). 613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 62acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the 63acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * certificate will be created with an invalid signature which will not verify. Such a certificate 64acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * is still useful because it provides access to the public key. To generate a valid 65acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * signature for the certificate the key needs to be authorized for 66acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * {@link KeyProperties#PURPOSE_SIGN}, a suitable digest or {@link KeyProperties#DIGEST_NONE}, and 67acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or 68acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * {@link KeyProperties#ENCRYPTION_PADDING_NONE}. 69acb7efd0d6dbde2506bb333e400a281f422df3fcAlex Klyubin * 703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key 713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * material of the public keys is accessible. 723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 731b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * <p>Instances of this class are immutable. 741b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * 753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p><h3>Example: Asymmetric key pair</h3> 763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an EC key pair in the Android KeyStore system 773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * under alias {@code key1} authorized to be used only for signing using SHA-256, SHA-384, 783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or SHA-512 digest and only if the user has been authenticated within the last five minutes. 793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code 803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( 813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyProperties.KEY_ALGORITHM_EC, 823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * "AndroidKeyStore"); 833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyPairGenerator.initialize( 841b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * new KeyGenParameterSpec.Builder( 851b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * "key1", 863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) 871b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * .setDigests(KeyProperties.DIGEST_SHA256, 881b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * KeyProperties.DIGEST_SHA384, 891b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * KeyProperties.DIGEST_SHA512) 903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // Only permit this key to be used if the user authenticated 913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // within the last five minutes. 923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .setUserAuthenticationRequired(true) 933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .setUserAuthenticationValidityDurationSeconds(5 * 60) 943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .build()); 953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyPair keyPair = keyPairGenerator.generateKeyPair(); 963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key pair can also be obtained from the Android Keystore any time as follows: 983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null); 1003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null); 1013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey(); 1023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre> 1033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 1043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p><h3>Example: Symmetric key</h3> 1053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * The following example illustrates how to generate an AES key in the Android KeyStore system under 106a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * alias {@code key2} authorized to be used only for encryption/decryption in GCM mode with no 107cb3bb3f03ac253052cd42a32a54e63c2ee9b9a95Alex Klyubin * padding. 1083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <pre> {@code 1093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyGenerator keyGenerator = KeyGenerator.getInstance( 1101b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * KeyProperties.KEY_ALGORITHM_AES, 1113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * "AndroidKeyStore"); 1123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyGenerator.initialize( 1133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * new KeyGenParameterSpec.Builder("key2", 1143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) 115a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 116a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 1173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * .build()); 1183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * SecretKey key = keyGenerator.generateKey(); 1193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 1203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * // The key can also be obtained from the Android Keystore any time as follows: 1213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 1223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keyStore.load(null); 1233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key = (SecretKey) keyStore.getKey("key2", null); 1243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * }</pre> 1253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 1263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinpublic final class KeyGenParameterSpec implements AlgorithmParameterSpec { 1273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake"); 1293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1"); 1303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970 1313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048 1323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final String mKeystoreAlias; 1343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final int mKeySize; 1353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final AlgorithmParameterSpec mSpec; 1363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final X500Principal mCertificateSubject; 1373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final BigInteger mCertificateSerialNumber; 1383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mCertificateNotBefore; 1393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mCertificateNotAfter; 1403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityStart; 1413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityForOriginationEnd; 1423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final Date mKeyValidityForConsumptionEnd; 1433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.PurposeEnum int mPurposes; 1443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.DigestEnum String[] mDigests; 1453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 1463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 1473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final @KeyProperties.BlockModeEnum String[] mBlockModes; 1483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final boolean mRandomizedEncryptionRequired; 1493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final boolean mUserAuthenticationRequired; 1503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final int mUserAuthenticationValidityDurationSeconds; 1513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 1533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @hide should be built with Builder 1543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 1553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public KeyGenParameterSpec( 1563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin String keyStoreAlias, 1573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin int keySize, 1583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin AlgorithmParameterSpec spec, 1593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin X500Principal certificateSubject, 1603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin BigInteger certificateSerialNumber, 1613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date certificateNotBefore, 1623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date certificateNotAfter, 1633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityStart, 1643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityForOriginationEnd, 1653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin Date keyValidityForConsumptionEnd, 1663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.PurposeEnum int purposes, 1673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.DigestEnum String[] digests, 1683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, 1693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.SignaturePaddingEnum String[] signaturePaddings, 1703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.BlockModeEnum String[] blockModes, 1713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin boolean randomizedEncryptionRequired, 1723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin boolean userAuthenticationRequired, 1733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin int userAuthenticationValidityDurationSeconds) { 1743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (TextUtils.isEmpty(keyStoreAlias)) { 1753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("keyStoreAlias must not be empty"); 1763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateSubject == null) { 1793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateSubject = DEFAULT_CERT_SUBJECT; 1803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotBefore == null) { 1823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateNotBefore = DEFAULT_CERT_NOT_BEFORE; 1833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotAfter == null) { 1853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateNotAfter = DEFAULT_CERT_NOT_AFTER; 1863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateSerialNumber == null) { 1883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin certificateSerialNumber = DEFAULT_CERT_SERIAL_NUMBER; 1893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (certificateNotAfter.before(certificateNotBefore)) { 1923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("certificateNotAfter < certificateNotBefore"); 1933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 1943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 1953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias = keyStoreAlias; 1963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize = keySize; 1973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec = spec; 1983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject = certificateSubject; 1993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber = certificateSerialNumber; 2001b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotBefore = Utils.cloneIfNotNull(certificateNotBefore); 2011b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotAfter = Utils.cloneIfNotNull(certificateNotAfter); 2021b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart); 2031b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd); 2041b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); 2053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes = purposes; 2063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests = ArrayUtils.cloneIfNotEmpty(digests); 2073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings = 2083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); 2093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); 2103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); 2113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired = randomizedEncryptionRequired; 2123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired = userAuthenticationRequired; 2133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; 2143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the alias that will be used in the {@code java.security.KeyStore} 2183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * in conjunction with the {@code AndroidKeyStore}. 2193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2201b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin @NonNull 2213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public String getKeystoreAlias() { 2223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mKeystoreAlias; 2233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2263ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * Returns the requested key size. If {@code -1}, the size should be looked up from 2273ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * {@link #getAlgorithmParameterSpec()}, if provided, otherwise an algorithm-specific default 2283ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * size should be used. 2293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public int getKeySize() { 2313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mKeySize; 2323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2351b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * Returns the key algorithm-specific {@link AlgorithmParameterSpec} that will be used for 2361b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * creation of the key or {@code null} if algorithm-specific defaults should be used. 2373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2381b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin @Nullable 2393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public AlgorithmParameterSpec getAlgorithmParameterSpec() { 2403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mSpec; 2413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the subject distinguished name to be used on the X.509 certificate that will be put 2453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * in the {@link java.security.KeyStore}. 2463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 2483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public X500Principal getCertificateSubject() { 2493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mCertificateSubject; 2503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the serial number to be used on the X.509 certificate that will be put in the 2543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 2553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 2573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public BigInteger getCertificateSerialNumber() { 2583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mCertificateSerialNumber; 2593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the start date to be used on the X.509 certificate that will be put in the 2633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 2643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 2663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getCertificateNotBefore() { 2671b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mCertificateNotBefore); 2683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the end date to be used on the X.509 certificate that will be put in the 2723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link java.security.KeyStore}. 2733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 2753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getCertificateNotAfter() { 2761b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mCertificateNotAfter); 2773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant before which the key is not yet valid or {@code null} if not 2813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * restricted. 2823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 2843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityStart() { 2851b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityStart); 2863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant after which the key is no longer valid for decryption and 2903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * verification or {@code null} if not restricted. 2913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 2923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 2933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityForConsumptionEnd() { 2941b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityForConsumptionEnd); 2953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 2963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 2973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 2983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the time instant after which the key is no longer valid for encryption and signing 2993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or {@code null} if not restricted. 3003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @Nullable 3023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Date getKeyValidityForOriginationEnd() { 3031b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin return Utils.cloneIfNotNull(mKeyValidityForOriginationEnd); 3043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. 3083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Attempts to use the key for any other purpose will be rejected. 3093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 3113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.PurposeEnum int getPurposes() { 3133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mPurposes; 3143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the 3183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key can be used or {@code null} if not specified. 3193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code DIGEST} constants. 3213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @throws IllegalStateException if this set has not been specified. 3233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #isDigestsSpecified() 3253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.DigestEnum String[] getDigests() { 3283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (mDigests == null) { 3293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalStateException("Digests not specified"); 3303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mDigests); 3323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns {@code true} if the set of digest algorithms with which the key can be used has been 3363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * specified. 3373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #getDigests() 3393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isDigestsSpecified() { 3423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mDigests != null; 3433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding}, 3473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when 3483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * encrypting/decrypting. Attempts to use the key with any other padding scheme will be 3493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 3503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 3523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { 3553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); 3563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 3603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * can be used when signing/verifying. Attempts to use the key with any other padding scheme 3613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * will be rejected. 3623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 3643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { 3673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); 3683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 371a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * Gets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be used 3723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * when encrypting/decrypting. Attempts to use the key with any other block modes will be 3733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 3743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 3763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 3783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public @KeyProperties.BlockModeEnum String[] getBlockModes() { 3793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return ArrayUtils.cloneIfNotEmpty(mBlockModes); 3803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns {@code true} if encryption using this key must be sufficiently randomized to produce 3843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * different ciphertexts for the same plaintext every time. The formal cryptographic property 3853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * being required is <em>indistinguishability under chosen-plaintext attack ({@code 3863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * IND-CPA})</em>. This property is important because it mitigates several classes of 3873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * weaknesses due to which ciphertext may leak information about plaintext. For example, if a 3883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * given plaintext always produces the same ciphertext, an attacker may see the repeated 3893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ciphertexts and be able to deduce something about the plaintext. 3903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 3913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isRandomizedEncryptionRequired() { 3923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mRandomizedEncryptionRequired; 3933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 3943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 3953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 3963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Returns {@code true} if user authentication is required for this key to be used. 3973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 3983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This restriction applies only to private key operations. Public key operations are not 3993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * restricted. 4003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #getUserAuthenticationValidityDurationSeconds() 4023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public boolean isUserAuthenticationRequired() { 4043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mUserAuthenticationRequired; 4053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Gets the duration of time (seconds) for which this key can be used after the user is 4093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * successfully authenticated. This has effect only if user authentication is required. 4103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This restriction applies only to private key operations. Public key operations are not 4123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * restricted. 4133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @return duration in seconds or {@code -1} if authentication is required for every use of the 4151b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * key. 4163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #isUserAuthenticationRequired() 4183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public int getUserAuthenticationValidityDurationSeconds() { 4203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return mUserAuthenticationValidityDurationSeconds; 4213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Builder of {@link KeyGenParameterSpec} instances. 4253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public final static class Builder { 4273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private final String mKeystoreAlias; 4283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.PurposeEnum int mPurposes; 4293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private int mKeySize = -1; 4313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private AlgorithmParameterSpec mSpec; 4323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private X500Principal mCertificateSubject; 4333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private BigInteger mCertificateSerialNumber; 4343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mCertificateNotBefore; 4353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mCertificateNotAfter; 4363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityStart; 4373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityForOriginationEnd; 4383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private Date mKeyValidityForConsumptionEnd; 4393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.DigestEnum String[] mDigests; 4403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; 4413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; 4423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private @KeyProperties.BlockModeEnum String[] mBlockModes; 4433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private boolean mRandomizedEncryptionRequired = true; 4443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private boolean mUserAuthenticationRequired; 4453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin private int mUserAuthenticationValidityDurationSeconds = -1; 4463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Creates a new instance of the {@code Builder}. 4493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param keystoreAlias alias of the entry in which the generated key will appear in 4511b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * Android KeyStore. Must not be empty. 4523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be 4533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * used. Attempts to use the key for any other purpose will be rejected. 4543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>If the set of purposes for which the key can be used does not contain 4563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by 4573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an 4583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * invalid signature. This is OK if the certificate is only used for obtaining the 4593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * public key from Android KeyStore. 4603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code PURPOSE} flags. 4623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) { 4643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (keystoreAlias == null) { 4653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("keystoreAlias == null"); 4661b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin } else if (keystoreAlias.isEmpty()) { 4671b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin throw new IllegalArgumentException("keystoreAlias must not be empty"); 4683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias = keystoreAlias; 4703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes = purposes; 4713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the size (in bits) of the key to be generated. For instance, for RSA keys this sets 4753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the modulus size, for EC keys this selects a curve with a matching field size, and for 4763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * symmetric keys this sets the size of the bitstring which is their key material. 4773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 4783ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * <p>The default key size is specific to each key algorithm. If key size is not set 4793ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * via this method, it should be looked up from the algorithm-specific parameters (if any) 4803ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * provided via 4813ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin * {@link #setAlgorithmParameterSpec(AlgorithmParameterSpec) setAlgorithmParameterSpec}. 4823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 4833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 4843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeySize(int keySize) { 4853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (keySize < 0) { 4863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new IllegalArgumentException("keySize < 0"); 4873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize = keySize; 4893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 4903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 4913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 4923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 4933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the algorithm-specific key generation parameters. For example, for RSA keys this may 4941b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec} whereas for EC keys 4951b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * this may be an instance of {@link java.security.spec.ECGenParameterSpec}. 4961b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * 4971b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * <p>These key generation parameters must match other explicitly set parameters (if any), 4981b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin * such as key size. 4993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) { 5013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (spec == null) { 5023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("spec == null"); 5033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec = spec; 5053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the subject used for the self-signed certificate of the generated key pair. 5103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the subject is {@code CN=fake}. 5123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateSubject(@NonNull X500Principal subject) { 5153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (subject == null) { 5163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("subject == null"); 5173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject = subject; 5193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the serial number used for the self-signed certificate of the generated key pair. 5243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the serial number is {@code 1}. 5263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateSerialNumber(@NonNull BigInteger serialNumber) { 5293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (serialNumber == null) { 5303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("serialNumber == null"); 5313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber = serialNumber; 5333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the start of the validity period for the self-signed certificate of the generated 5383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * key pair. 5393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, this date is {@code Jan 1 1970}. 5413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateNotBefore(@NonNull Date date) { 5443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (date == null) { 5453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("date == null"); 5463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5471b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotBefore = Utils.cloneIfNotNull(date); 5483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the end of the validity period for the self-signed certificate of the generated key 5533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * pair. 5543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, this date is {@code Jan 1 2048}. 5563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setCertificateNotAfter(@NonNull Date date) { 5593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (date == null) { 5603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin throw new NullPointerException("date == null"); 5613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5621b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mCertificateNotAfter = Utils.cloneIfNotNull(date); 5633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant before which the key is not yet valid. 5683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 5703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityEnd(Date) 5723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityStart(Date startDate) { 5751b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityStart = Utils.cloneIfNotNull(startDate); 5763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid. 5813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 5833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityStart(Date) 5853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForConsumptionEnd(Date) 5863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForOriginationEnd(Date) 5873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 5883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 5893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityEnd(Date endDate) { 5903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin setKeyValidityForOriginationEnd(endDate); 5913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin setKeyValidityForConsumptionEnd(endDate); 5923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 5933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 5943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 5953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 5963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid for encryption and signing. 5973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 5983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 5993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForConsumptionEnd(Date) 6013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityForOriginationEnd(Date endDate) { 6041b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(endDate); 6053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the time instant after which the key is no longer valid for decryption and 6103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * verification. 6113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key is valid at any instant. 6133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6143f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setKeyValidityForOriginationEnd(Date) 6153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setKeyValidityForConsumptionEnd(Date endDate) { 6181b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(endDate); 6193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which 6243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * the key can be used when signing/verifying. Attempts to use the key with any other digest 6253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * algorithm will be rejected. 6263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This must be specified for keys which are used for signing/verification. For HMAC 6283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * keys, the set of digests defaults to the digest associated with the key algorithm (e.g., 629dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * {@code SHA-256} for key algorithm {@code HmacSHA256}). 6303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 631dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>For private keys used for TLS/SSL client or server authentication it is usually 632dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is 633dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * because TLS/SSL stacks typically generate the necessary digest(s) themselves and then use 634dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * a private key to sign it. 635dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * 636dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>See {@link KeyProperties}.{@code DIGEST} constants. 6373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setDigests(@KeyProperties.DigestEnum String... digests) { 6403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests = ArrayUtils.cloneIfNotEmpty(digests); 6413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding}, 6463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when 6473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * encrypting/decrypting. Attempts to use the key with any other padding scheme will be 6483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * rejected. 6493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This must be specified for keys which are used for encryption/decryption. 6513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 652dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it 653dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * is usually necessary to authorize the use of no/any padding 654dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is 655dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * required by some cipher suites, and some stacks request decryption using no padding 656dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * whereas others request PKCS#1 padding. 657dcf3d35f23ba46f17251d4181eee4675691f3380Alex Klyubin * 6583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants. 6593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setEncryptionPaddings( 6623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.EncryptionPaddingEnum String... paddings) { 6633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings); 6643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key 6693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * can be used when signing/verifying. Attempts to use the key with any other padding scheme 6703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * will be rejected. 6713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This must be specified for RSA keys which are used for signing/verification. 6733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants. 6753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setSignaturePaddings( 6783f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @KeyProperties.SignaturePaddingEnum String... paddings) { 6793f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings); 6803f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 684a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * Sets the set of block modes (e.g., {@code GCM}, {@code CBC}) with which the key can be 685a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * used when encrypting/decrypting. Attempts to use the key with any other block modes will 686a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * be rejected. 6873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 688a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * <p>This must be specified for symmetric encryption/decryption keys. 6893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 6903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants. 6913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 6923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 6933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) { 6943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes); 6953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 6963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 6973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 6983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 6993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets whether encryption using this key must be sufficiently randomized to produce 7003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * different ciphertexts for the same plaintext every time. The formal cryptographic 7013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * property being required is <em>indistinguishability under chosen-plaintext attack 7023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ({@code IND-CPA})</em>. This property is important because it mitigates several classes 7033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * of weaknesses due to which ciphertext may leak information about plaintext. For example, 7043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * if a given plaintext always produces the same ciphertext, an attacker may see the 7053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * repeated ciphertexts and be able to deduce something about the plaintext. 7063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, {@code IND-CPA} is required. 7083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>When {@code IND-CPA} is required: 7103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <ul> 7113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as 7123f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without 7133f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * padding, are prohibited;</li> 714a5e21f0ee2fbf3a6f03e31fca8da459e1fe9e213Alex Klyubin * <li>in block modes which use an IV, such as {@code GCM}, {@code CBC}, and {@code CTR}, 7153f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are 7163f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * used.</li> 7173f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * </ul> 7183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7193f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>Before disabling this requirement, consider the following approaches instead: 7203f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <ul> 7213f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are generating a random IV for encryption and then initializing a {@code} 7223f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV 7233f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * instead. This will occur if the {@code Cipher} is initialized for encryption without an 7243f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * IV. The IV can then be queried via {@link Cipher#getIV()}.</li> 7253f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully 7263f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * random, such as the name of the file being encrypted, or transaction ID, or password, 7273f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * or a device identifier), consider changing your design to use a random IV which will then 7283f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * be provided in addition to the ciphertext to the entities which need to decrypt the 7293f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * ciphertext.</li> 7303f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <li>If you are using RSA encryption without padding, consider switching to encryption 7313f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * padding schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li> 7323f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * </ul> 7333f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7343f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7353f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setRandomizedEncryptionRequired(boolean required) { 7363f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired = required; 7373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets whether user authentication is required to use this key. 7423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7433f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the key can be used without user authentication. 7443f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7453f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>When user authentication is required, the user authorizes the use of the key by 7463f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * authenticating to this Android device using a subset of their secure lock screen 7473f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * credentials. Different authentication methods are used depending on whether the every 7483f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * use of the key must be authenticated (as specified by 7493f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * {@link #setUserAuthenticationValidityDurationSeconds(int)}). 7503f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More 7513f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * information</a>. 7523f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7533f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>This restriction applies only to private key operations. Public key operations are not 7543f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * restricted. 7553f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7563f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setUserAuthenticationValidityDurationSeconds(int) 7573f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7583f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7593f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setUserAuthenticationRequired(boolean required) { 7603f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired = required; 7613f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7623f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7633f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7643f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7653f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Sets the duration of time (seconds) for which this key can be used after the user is 7663f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * successfully authenticated. This has effect only if user authentication is required. 7673f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7683f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * <p>By default, the user needs to authenticate for every use of the key. 7693f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7703f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for 7713f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * every use of the key. 7723f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * 7733f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * @see #setUserAuthenticationRequired(boolean) 7743f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7753f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7763f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public Builder setUserAuthenticationValidityDurationSeconds( 7773f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @IntRange(from = -1) int seconds) { 7781b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin if (seconds < -1) { 7791b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin throw new IllegalArgumentException("seconds must be -1 or larger"); 7801b937eebdd38a7bea9b86831370a78bcded4d63cAlex Klyubin } 7813f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationValidityDurationSeconds = seconds; 7823f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return this; 7833f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 7843f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin 7853f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin /** 7863f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin * Builds an instance of {@code KeyGenParameterSpec}. 7873f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin */ 7883f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin @NonNull 7893f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin public KeyGenParameterSpec build() { 7903f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin return new KeyGenParameterSpec( 7913f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeystoreAlias, 7923f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeySize, 7933f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSpec, 7943f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSubject, 7953f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateSerialNumber, 7963f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateNotBefore, 7973f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mCertificateNotAfter, 7983f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityStart, 7993f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityForOriginationEnd, 8003f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mKeyValidityForConsumptionEnd, 8013f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mPurposes, 8023f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mDigests, 8033f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mEncryptionPaddings, 8043f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mSignaturePaddings, 8053f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mBlockModes, 8063f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mRandomizedEncryptionRequired, 8073f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationRequired, 8083f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mUserAuthenticationValidityDurationSeconds); 8093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8103f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } 8113f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin} 812