Most visited

Recently visited

Added in API level 23

KeyGenParameterSpec

public final class KeyGenParameterSpec
extends Object implements AlgorithmParameterSpec

java.lang.Object
   ↳ android.security.keystore.KeyGenParameterSpec


AlgorithmParameterSpec用于初始化KeyPairGeneratorKeyGeneratorKeyGenerator 该规范确定了密钥的授权使用,例如是否需要使用密钥的用户身份验证,授权哪些操作(例如签名,但不解密),使用哪些参数(例如,只使用特定的填充方案或摘要) ,以及密钥的有效开始和结束日期。 规范中表达的密钥使用授权仅适用于密钥和私钥 - 公钥可用于任何支持的操作。

为了产生非对称密钥对或对称密钥,创建使用此类的实例 KeyGenParameterSpec.Builder ,初始化 KeyPairGeneratorKeyGenerator (例如,所期望的密钥类型的 ECAES -见 KeyPropertiesKEY_ALGORITHM从常量) AndroidKeyStore提供商使用 KeyGenParameterSpec实例,然后使用 generateKey()generateKeyPair()生成密钥或密钥对。

生成的密钥对或密钥将由生成器返回,并存储在Android规范中指定的别名下的Android密钥库中。 要从Android密钥库中获取密钥或私钥,请使用KeyStore.getKey(String, null)KeyStore.getEntry(String, null) 要从Android密钥库获取公钥,请使用getCertificate(String) ,然后使用getPublicKey()

为了帮助获取存储在Android Keystore中的密钥对的算法特定公共参数,生成的私钥实现了 ECKeyRSAKey接口,而公钥实现了 ECPublicKeyRSAPublicKey接口。

对于非对称密钥对,还会生成自签名X.509证书并存储在Android密钥库中。 这是因为KeyStore抽象不支持存储没有证书的密钥对。 本规范中可定制证书的主题,序列号和有效日期。 自签名证书可能会在稍后由证书颁发机构(CA)签署的证书替换。

注意:如果私钥没有被授权对自签名证书进行签名,则证书将被创建为具有无法验证的无效签名。 这样的证书仍然有用,因为它提供了对公钥的访问。 为了生成证书的有效签名,密钥需要被授权以下所有内容:

注意:生成的对称密钥和专用密钥的密钥材料不可访问。 公钥的关键材料是可访问的。

这个类的实例是不可变的。

Known issues

A known bug in Android 6.0 (API Level 23) causes user authentication-related authorizations to be enforced even for public keys. To work around this issue extract the public key material to use outside of Android Keystore. For example:
 PublicKey unrestrictedPublicKey =
         KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic(
                 new X509EncodedKeySpec(publicKey.getEncoded()));
 

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

This example illustrates how to generate a NIST P-256 (aka secp256r1 aka prime256v1) EC key pair in the Android KeyStore system under alias key1 where the private key is authorized to be used only for signing using SHA-256, SHA-384, or SHA-512 digest and only if the user has been authenticated within the last five minutes. The use of the public key is unrestricted (See Known Issues).
 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
         KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
 keyPairGenerator.initialize(
         new KeyGenParameterSpec.Builder(
                 "key1",
                 KeyProperties.PURPOSE_SIGN)
                 .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                 .setDigests(KeyProperties.DIGEST_SHA256,
                         KeyProperties.DIGEST_SHA384,
                         KeyProperties.DIGEST_SHA512)
                 // Only permit the private key to be used if the user authenticated
                 // within the last five minutes.
                 .setUserAuthenticationRequired(true)
                 .setUserAuthenticationValidityDurationSeconds(5 * 60)
                 .build());
 KeyPair keyPair = keyPairGenerator.generateKeyPair();
 Signature signature = Signature.getInstance("SHA256withECDSA");
 signature.initSign(keyPair.getPrivate());
 ...

 // The key pair can also be obtained from the Android Keystore any time as follows:
 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
 keyStore.load(null);
 PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
 PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
 

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

This example illustrates how to generate an RSA key pair in the Android KeyStore system under alias key1 authorized to be used only for signing using the RSA-PSS signature padding scheme with SHA-256 or SHA-512 digests. The use of the public key is unrestricted.
 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
 keyPairGenerator.initialize(
         new KeyGenParameterSpec.Builder(
                 "key1",
                 KeyProperties.PURPOSE_SIGN)
                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                 .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
                 .build());
 KeyPair keyPair = keyPairGenerator.generateKeyPair();
 Signature signature = Signature.getInstance("SHA256withRSA/PSS");
 signature.initSign(keyPair.getPrivate());
 ...

 // The key pair can also be obtained from the Android Keystore any time as follows:
 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
 keyStore.load(null);
 PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
 PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
 

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

This example illustrates how to generate an RSA key pair in the Android KeyStore system under alias key1 where the private key is authorized to be used only for decryption using RSA OAEP encryption padding scheme with SHA-256 or SHA-512 digests. The use of the public key is unrestricted.
 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
         KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
 keyPairGenerator.initialize(
         new KeyGenParameterSpec.Builder(
                 "key1",
                 KeyProperties.PURPOSE_DECRYPT)
                 .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                 .build());
 KeyPair keyPair = keyPairGenerator.generateKeyPair();
 Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
 cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
 ...

 // The key pair can also be obtained from the Android Keystore any time as follows:
 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
 keyStore.load(null);
 PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
 PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
 

Example: AES key for encryption/decryption in GCM mode

The following example illustrates how to generate an AES key in the Android KeyStore system under alias key2 authorized to be used only for encryption/decryption in GCM mode with no padding.
 KeyGenerator keyGenerator = KeyGenerator.getInstance(
         KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
 keyGenerator.initialize(
         new KeyGenParameterSpec.Builder("key2",
                 KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                 .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                 .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                 .build());
 SecretKey key = keyGenerator.generateKey();

 Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
 cipher.init(Cipher.ENCRYPT_MODE, key);
 ...

 // The key can also be obtained from the Android Keystore any time as follows:
 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
 keyStore.load(null);
 key = (SecretKey) keyStore.getKey("key2", null);
 

Example: HMAC key for generating a MAC using SHA-256

This example illustrates how to generate an HMAC key in the Android KeyStore system under alias key2 authorized to be used only for generating an HMAC using SHA-256.
 KeyGenerator keyGenerator = KeyGenerator.getInstance(
         KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
 keyGenerator.initialize(
         new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build());
 SecretKey key = keyGenerator.generateKey();
 Mac mac = Mac.getInstance("HmacSHA256");
 mac.init(key);
 ...

 // The key can also be obtained from the Android Keystore any time as follows:
 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
 keyStore.load(null);
 key = (SecretKey) keyStore.getKey("key2", null);
 

Summary

Nested classes

class KeyGenParameterSpec.Builder

KeyGenParameterSpec实例的构建者。

Public methods

AlgorithmParameterSpec getAlgorithmParameterSpec()

如果应使用算法特定的默认值,则返回将用于创建密钥的特定关键算法 AlgorithmParameterSpecnull

byte[] getAttestationChallenge()

返回将放置在此密钥对的证明证书中的证明质询值。

String[] getBlockModes()

获取该组块模式(例如, GCMCBC )与该密钥可以加密/解密时使用。

Date getCertificateNotAfter()

返回将放入 KeyStore的X.509证书上使用的结束日期。

Date getCertificateNotBefore()

返回将放入 KeyStore的X.509证书上使用的开始日期。

BigInteger getCertificateSerialNumber()

返回将放入 KeyStore的X.509证书上使用的序列号。

X500Principal getCertificateSubject()

返回要置于 KeyStore的X.509证书上要使用的主题专有名称。

String[] getDigests()

返回所述一组摘要算法(例如, SHA-256SHA-384与该密钥可以用于或 null ,如果没有指定。

String[] getEncryptionPaddings()

返回该组的填充方案(例如, PKCS7PaddingOEAPPaddingPKCS1PaddingNoPadding )与该密钥可以加密/解密时使用。

int getKeySize()

返回请求的密钥大小。

Date getKeyValidityForConsumptionEnd()

返回密钥不再有效用于解密和验证的 null如果不受限制,则 null

Date getKeyValidityForOriginationEnd()

返回密钥不再有效用于加密和签名的 null如果不受限制,则 null

Date getKeyValidityStart()

返回密钥尚未生效的瞬间时间,如果不受限制,则返回 null

String getKeystoreAlias()

返回将与 java.security.KeyStore结合使用的 java.security.KeyStore中使用的 AndroidKeyStore

int getPurposes()

返回可以使用密钥的一组目的(例如,加密,解密,签名)。

String[] getSignaturePaddings()

获取一组填充方案(例如, PSSPKCS#1 )与该密钥可以签名/验证时使用。

int getUserAuthenticationValidityDurationSeconds()

获取用户成功通过身份验证后授权使用此密钥的持续时间(秒)。

boolean isDigestsSpecified()

如果指定了可以使用密钥的一组摘要算法,则返回 true

boolean isInvalidatedByBiometricEnrollment()

返回 true如果在注册新指纹或删除所有登记指纹时密钥不可逆转地失效。

boolean isRandomizedEncryptionRequired()

返回 true如果使用此密钥的加密必须足够随机化,以便每次为相同的明文生成不同的密文。

boolean isUserAuthenticationRequired()

如果密钥仅在用户已通过身份验证时才有权使用,则返回 true

boolean isUserAuthenticationValidWhileOnBody()

如果密钥仅在设备从用户身体移除之前保持授权,则返回 true ,直到有效期限。

Inherited methods

From class java.lang.Object

Public methods

getAlgorithmParameterSpec

Added in API level 23
AlgorithmParameterSpec getAlgorithmParameterSpec ()

如果应该使用特定于算法的默认值,则返回将用于创建密钥的关键算法 AlgorithmParameterSpecnull

Returns
AlgorithmParameterSpec

getAttestationChallenge

Added in API level 24
byte[] getAttestationChallenge ()

返回将放置在此密钥对的证明证书中的证明质询值。

如果此方法返回非null ,则此密钥对的公钥证书将包含一个扩展,该扩展描述密钥配置和授权的详细信息,包括证明质询值的内容。 如果密钥处于安全硬件中,并且安全硬件支持证明,则证书将通过以可信CA密钥为根的证书链进行签名。 否则,该链将植根于不受信任的证书。

如果此方法返回null ,并且该规范用于生成非对称(RSA或EC)密钥对,则公钥将具有自签名证书(如果其具有目的PURPOSE_SIGN 如果没有目的PURPOSE_SIGN ,它将有一个假证书。

对称密钥(如AES和HMAC密钥)没有公钥证书。 如果带有getAttestationChallenge的KeyGenParameterSpec返回非空值用于生成对称(AES或HMAC)密钥,则generateKey()将抛出InvalidAlgorithmParameterException

Returns
byte[]

也可以看看:

getBlockModes

Added in API level 23
String[] getBlockModes ()

获取该组块模式(例如, GCMCBC )与该密钥可以加密/解密时使用。 试图在任何其他模块模式下使用密钥将被拒绝。

KeyProperties BLOCK_MODE常量。

Returns
String[]

getCertificateNotAfter

Added in API level 23
Date getCertificateNotAfter ()

返回将放入 KeyStore的X.509证书上使用的结束日期。

Returns
Date

getCertificateNotBefore

Added in API level 23
Date getCertificateNotBefore ()

返回将放入 KeyStore的X.509证书上使用的开始日期。

Returns
Date

getCertificateSerialNumber

Added in API level 23
BigInteger getCertificateSerialNumber ()

返回将放入 KeyStore的X.509证书上使用的序列号。

Returns
BigInteger

getCertificateSubject

Added in API level 23
X500Principal getCertificateSubject ()

返回要放入 KeyStore的X.509证书上要使用的主题专有名称。

Returns
X500Principal

getDigests

Added in API level 23
String[] getDigests ()

返回所述一组摘要算法(例如, SHA-256SHA-384与该密钥可以用于或 null ,如果没有指定。

KeyProperties DIGEST常数。

Returns
String[]
Throws
IllegalStateException if this set has not been specified.

也可以看看:

getEncryptionPaddings

Added in API level 23
String[] getEncryptionPaddings ()

返回该组的填充方案(例如, PKCS7PaddingOEAPPaddingPKCS1PaddingNoPadding )与该密钥可以加密/解密时使用。 尝试将密钥与任何其他填充方案一起使用将被拒绝。

KeyProperties ENCRYPTION_PADDING常数。

Returns
String[]

getKeySize

Added in API level 23
int getKeySize ()

返回请求的密钥大小。 如果为-1 ,则应从getAlgorithmParameterSpec()查找大小(如果提供),否则应使用算法特定的默认大小。

Returns
int

getKeyValidityForConsumptionEnd

Added in API level 23
Date getKeyValidityForConsumptionEnd ()

返回密钥不再有效用于解密和验证的 null如果不受限制,则 null

Returns
Date

getKeyValidityForOriginationEnd

Added in API level 23
Date getKeyValidityForOriginationEnd ()

返回密钥不再有效用于加密和签名的 null如果不受限制,则 null

Returns
Date

getKeyValidityStart

Added in API level 23
Date getKeyValidityStart ()

返回密钥尚未生效的瞬间时间,如果不受限制,则返回 null

Returns
Date

getKeystoreAlias

Added in API level 23
String getKeystoreAlias ()

返回将与 java.security.KeyStore结合使用的 java.security.KeyStore中使用的 AndroidKeyStore

Returns
String

getPurposes

Added in API level 23
int getPurposes ()

返回可以使用密钥的一组目的(例如,加密,解密,签名)。 试图将钥匙用于任何其他目的将被拒绝。

KeyProperties PURPOSE标志。

Returns
int

getSignaturePaddings

Added in API level 23
String[] getSignaturePaddings ()

获取一组填充方案(例如, PSSPKCS#1 )与该密钥可以签名/验证时使用。 尝试将密钥与任何其他填充方案一起使用将被拒绝。

KeyProperties SIGNATURE_PADDING常数。

Returns
String[]

getUserAuthenticationValidityDurationSeconds

Added in API level 23
int getUserAuthenticationValidityDurationSeconds ()

获取用户成功通过身份验证后授权使用此密钥的持续时间(秒)。 这仅在需要用户认证时才有效(请参阅isUserAuthenticationRequired() )。

此授权仅适用于密钥和私钥操作。 公钥操作不受限制。

Returns
int duration in seconds or -1 if authentication is required for every use of the key.

也可以看看:

isDigestsSpecified

Added in API level 23
boolean isDigestsSpecified ()

如果指定了可以使用密钥的一组摘要算法,则返回 true

Returns
boolean

也可以看看:

isInvalidatedByBiometricEnrollment

Added in API level 24
boolean isInvalidatedByBiometricEnrollment ()

返回true如果在注册新指纹或删除所有登记指纹时密钥不可逆转地失效。 这只对需要指纹用户验证才能用于每次使用的密钥有效。

Returns
boolean

也可以看看:

isRandomizedEncryptionRequired

Added in API level 23
boolean isRandomizedEncryptionRequired ()

如果使用此密钥的加密必须足够随机化,以便每次为相同的明文生成不同的密文,则返回true 所需的正式密码属性在选择明文攻击下不可区分的( IND-CPA 这个属性很重要,因为它可以缓解由于密文泄露明文信息而导致的几类弱点。 例如,如果一个给定的明文总是产生相同的密文,攻击者可能会看到重复的密文,并能够推断出有关明文的信息。

Returns
boolean

isUserAuthenticationRequired

Added in API level 23
boolean isUserAuthenticationRequired ()

如果密钥仅在用户已通过身份验证时才有权使用,则返回 true

此授权仅适用于密钥和私钥操作。 公钥操作不受限制。

Returns
boolean

也可以看看:

isUserAuthenticationValidWhileOnBody

Added in API level 24
boolean isUserAuthenticationValidWhileOnBody ()

如果密钥仅在设备从用户身体移除之前保持授权,则返回true ,直到有效期限。 此选项对没有验证有效期的密钥不起作用,如果设备缺少贴身传感器,则该选项无效。

授权仅适用于密钥和私钥操作。 公钥操作不受限制。

Returns
boolean

也可以看看:

Hooray!