public final class KeyGenParameterSpec
extends Object
implements AlgorithmParameterSpec
java.lang.Object | |
↳ | android.security.keystore.KeyGenParameterSpec |
AlgorithmParameterSpec
用于初始化KeyPairGenerator
或KeyGenerator
的KeyGenerator 。 该规范确定了密钥的授权使用,例如是否需要使用密钥的用户身份验证,授权哪些操作(例如签名,但不解密),使用哪些参数(例如,只使用特定的填充方案或摘要) ,以及密钥的有效开始和结束日期。 规范中表达的密钥使用授权仅适用于密钥和私钥 - 公钥可用于任何支持的操作。
为了产生非对称密钥对或对称密钥,创建使用此类的实例 KeyGenParameterSpec.Builder
,初始化 KeyPairGenerator
或 KeyGenerator
(例如,所期望的密钥类型的 EC
或 AES
-见 KeyProperties
。 KEY_ALGORITHM
从常量) AndroidKeyStore
提供商使用 KeyGenParameterSpec
实例,然后使用 generateKey()
或 generateKeyPair()
生成密钥或密钥对。
生成的密钥对或密钥将由生成器返回,并存储在Android规范中指定的别名下的Android密钥库中。 要从Android密钥库中获取密钥或私钥,请使用KeyStore.getKey(String, null)
或KeyStore.getEntry(String, null)
。 要从Android密钥库获取公钥,请使用getCertificate(String)
,然后使用getPublicKey()
。
为了帮助获取存储在Android Keystore中的密钥对的算法特定公共参数,生成的私钥实现了 ECKey
或 RSAKey
接口,而公钥实现了 ECPublicKey
或 RSAPublicKey
接口。
对于非对称密钥对,还会生成自签名X.509证书并存储在Android密钥库中。 这是因为KeyStore
抽象不支持存储没有证书的密钥对。 本规范中可定制证书的主题,序列号和有效日期。 自签名证书可能会在稍后由证书颁发机构(CA)签署的证书替换。
注意:如果私钥没有被授权对自签名证书进行签名,则证书将被创建为具有无法验证的无效签名。 这样的证书仍然有用,因为它提供了对公钥的访问。 为了生成证书的有效签名,密钥需要被授权以下所有内容:
PURPOSE_SIGN
,setUserAuthenticationRequired(boolean)
),setKeyValidityStart(Date)
and setKeyValidityForOriginationEnd(Date)
),SIGNATURE_PADDING_RSA_PKCS1
.注意:生成的对称密钥和专用密钥的密钥材料不可访问。 公钥的关键材料是可访问的。
这个类的实例是不可变的。
PublicKey unrestrictedPublicKey =
KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic(
new X509EncodedKeySpec(publicKey.getEncoded()));
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();
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();
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();
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);
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);
Nested classes |
|
---|---|
class |
KeyGenParameterSpec.Builder |
Public methods |
|
---|---|
AlgorithmParameterSpec |
getAlgorithmParameterSpec() 如果应使用算法特定的默认值,则返回将用于创建密钥的特定关键算法 |
byte[] |
getAttestationChallenge() 返回将放置在此密钥对的证明证书中的证明质询值。 |
String[] |
getBlockModes() 获取该组块模式(例如, |
Date |
getCertificateNotAfter() 返回将放入 |
Date |
getCertificateNotBefore() 返回将放入 |
BigInteger |
getCertificateSerialNumber() 返回将放入 |
X500Principal |
getCertificateSubject() 返回要置于 |
String[] |
getDigests() 返回所述一组摘要算法(例如, |
String[] |
getEncryptionPaddings() 返回该组的填充方案(例如, |
int |
getKeySize() 返回请求的密钥大小。 |
Date |
getKeyValidityForConsumptionEnd() 返回密钥不再有效用于解密和验证的 |
Date |
getKeyValidityForOriginationEnd() 返回密钥不再有效用于加密和签名的 |
Date |
getKeyValidityStart() 返回密钥尚未生效的瞬间时间,如果不受限制,则返回 |
String |
getKeystoreAlias() 返回将与 |
int |
getPurposes() 返回可以使用密钥的一组目的(例如,加密,解密,签名)。 |
String[] |
getSignaturePaddings() 获取一组填充方案(例如, |
int |
getUserAuthenticationValidityDurationSeconds() 获取用户成功通过身份验证后授权使用此密钥的持续时间(秒)。 |
boolean |
isDigestsSpecified() 如果指定了可以使用密钥的一组摘要算法,则返回 |
boolean |
isInvalidatedByBiometricEnrollment() 返回 |
boolean |
isRandomizedEncryptionRequired() 返回 |
boolean |
isUserAuthenticationRequired() 如果密钥仅在用户已通过身份验证时才有权使用,则返回 |
boolean |
isUserAuthenticationValidWhileOnBody() 如果密钥仅在设备从用户身体移除之前保持授权,则返回 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
AlgorithmParameterSpec getAlgorithmParameterSpec ()
如果应该使用特定于算法的默认值,则返回将用于创建密钥的关键算法 AlgorithmParameterSpec
或 null
。
Returns | |
---|---|
AlgorithmParameterSpec |
byte[] getAttestationChallenge ()
返回将放置在此密钥对的证明证书中的证明质询值。
如果此方法返回非null
,则此密钥对的公钥证书将包含一个扩展,该扩展描述密钥配置和授权的详细信息,包括证明质询值的内容。 如果密钥处于安全硬件中,并且安全硬件支持证明,则证书将通过以可信CA密钥为根的证书链进行签名。 否则,该链将植根于不受信任的证书。
如果此方法返回null
,并且该规范用于生成非对称(RSA或EC)密钥对,则公钥将具有自签名证书(如果其具有目的PURPOSE_SIGN
。 如果没有目的PURPOSE_SIGN
,它将有一个假证书。
对称密钥(如AES和HMAC密钥)没有公钥证书。 如果带有getAttestationChallenge的KeyGenParameterSpec返回非空值用于生成对称(AES或HMAC)密钥,则generateKey()
将抛出InvalidAlgorithmParameterException
。
Returns | |
---|---|
byte[] |
String[] getBlockModes ()
获取该组块模式(例如, GCM
, CBC
)与该密钥可以加密/解密时使用。 试图在任何其他模块模式下使用密钥将被拒绝。
见KeyProperties
。 BLOCK_MODE
常量。
Returns | |
---|---|
String[] |
Date getCertificateNotAfter ()
返回将放入 KeyStore
的X.509证书上使用的结束日期。
Returns | |
---|---|
Date |
Date getCertificateNotBefore ()
返回将放入 KeyStore
的X.509证书上使用的开始日期。
Returns | |
---|---|
Date |
BigInteger getCertificateSerialNumber ()
返回将放入 KeyStore
的X.509证书上使用的序列号。
Returns | |
---|---|
BigInteger |
X500Principal getCertificateSubject ()
返回要放入 KeyStore
的X.509证书上要使用的主题专有名称。
Returns | |
---|---|
X500Principal |
String[] getDigests ()
返回所述一组摘要算法(例如, SHA-256
, SHA-384
与该密钥可以用于或 null
,如果没有指定。
见KeyProperties
。 DIGEST
常数。
Returns | |
---|---|
String[] |
Throws | |
---|---|
IllegalStateException |
if this set has not been specified. |
也可以看看:
String[] getEncryptionPaddings ()
返回该组的填充方案(例如, PKCS7Padding
, OEAPPadding
, PKCS1Padding
, NoPadding
)与该密钥可以加密/解密时使用。 尝试将密钥与任何其他填充方案一起使用将被拒绝。
见KeyProperties
。 ENCRYPTION_PADDING
常数。
Returns | |
---|---|
String[] |
int getKeySize ()
返回请求的密钥大小。 如果为-1
,则应从getAlgorithmParameterSpec()
查找大小(如果提供),否则应使用算法特定的默认大小。
Returns | |
---|---|
int |
Date getKeyValidityForConsumptionEnd ()
返回密钥不再有效用于解密和验证的 null
如果不受限制,则 null
。
Returns | |
---|---|
Date |
Date getKeyValidityForOriginationEnd ()
返回密钥不再有效用于加密和签名的 null
如果不受限制,则 null
。
Returns | |
---|---|
Date |
Date getKeyValidityStart ()
返回密钥尚未生效的瞬间时间,如果不受限制,则返回 null
。
Returns | |
---|---|
Date |
String getKeystoreAlias ()
返回将与 java.security.KeyStore
结合使用的 java.security.KeyStore
中使用的 AndroidKeyStore
。
Returns | |
---|---|
String |
int getPurposes ()
返回可以使用密钥的一组目的(例如,加密,解密,签名)。 试图将钥匙用于任何其他目的将被拒绝。
见KeyProperties
。 PURPOSE
标志。
Returns | |
---|---|
int |
String[] getSignaturePaddings ()
获取一组填充方案(例如, PSS
, PKCS#1
)与该密钥可以签名/验证时使用。 尝试将密钥与任何其他填充方案一起使用将被拒绝。
见KeyProperties
。 SIGNATURE_PADDING
常数。
Returns | |
---|---|
String[] |
int getUserAuthenticationValidityDurationSeconds ()
获取用户成功通过身份验证后授权使用此密钥的持续时间(秒)。 这仅在需要用户认证时才有效(请参阅isUserAuthenticationRequired()
)。
此授权仅适用于密钥和私钥操作。 公钥操作不受限制。
Returns | |
---|---|
int |
duration in seconds or -1 if authentication is required for every use of the key. |
boolean isDigestsSpecified ()
如果指定了可以使用密钥的一组摘要算法,则返回 true
。
Returns | |
---|---|
boolean |
也可以看看:
boolean isInvalidatedByBiometricEnrollment ()
返回true
如果在注册新指纹或删除所有登记指纹时密钥不可逆转地失效。 这只对需要指纹用户验证才能用于每次使用的密钥有效。
Returns | |
---|---|
boolean |
boolean isRandomizedEncryptionRequired ()
如果使用此密钥的加密必须足够随机化,以便每次为相同的明文生成不同的密文,则返回true
。 所需的正式密码属性在选择明文攻击下是不可区分的( IND-CPA
) 。 这个属性很重要,因为它可以缓解由于密文泄露明文信息而导致的几类弱点。 例如,如果一个给定的明文总是产生相同的密文,攻击者可能会看到重复的密文,并能够推断出有关明文的信息。
Returns | |
---|---|
boolean |
boolean isUserAuthenticationRequired ()
如果密钥仅在用户已通过身份验证时才有权使用,则返回 true
。
此授权仅适用于密钥和私钥操作。 公钥操作不受限制。
Returns | |
---|---|
boolean |
boolean isUserAuthenticationValidWhileOnBody ()
如果密钥仅在设备从用户身体移除之前保持授权,则返回true
,直到有效期限。 此选项对没有验证有效期的密钥不起作用,如果设备缺少贴身传感器,则该选项无效。
授权仅适用于密钥和私钥操作。 公钥操作不受限制。
Returns | |
---|---|
boolean |