KeyProtection 类

定义

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

[Android.Runtime.Register("android/security/keystore/KeyProtection", ApiSince=23, DoNotGenerateAcw=true)]
public sealed class KeyProtection : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.Security.KeyStore.IProtectionParameter
[<Android.Runtime.Register("android/security/keystore/KeyProtection", ApiSince=23, DoNotGenerateAcw=true)>]
type KeyProtection = class
    inherit Object
    interface KeyStore.IProtectionParameter
    interface IJavaObject
    interface IDisposable
    interface IJavaPeerable
继承
KeyProtection
属性
实现

注解

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。 此类指定已导入密钥的授权使用,例如用户身份验证是使用密钥所必需的,密钥是授权哪些操作(例如解密,但未签名),以及具有哪些参数(例如,仅具有特定填充方案或摘要),以及密钥的有效性开始日期和结束日期。 此类中表示的密钥使用授权仅适用于密钥和私钥 -- 公钥可用于任何受支持的操作。

若要将密钥或密钥对导入到 Android 密钥存储中,请使用 Builder 此类的实例并使用导入的密钥或密钥对来创建 java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry 此类的实例。

若要从 Android 密钥存储获取机密/对称或私钥,请使用 java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)。 从 Android 密钥存储使用 java.security.KeyStore#getCertificate(String) 中获取公钥,然后 Certificate#getPublicKey()获取公钥。

为了帮助获取存储在 Android 密钥存储中的密钥对的算法特定的公钥参数,其私钥实现java.security.interfaces.ECKey或接口,而其公钥实现java.security.interfaces.ECPublicKeyjava.security.interfaces.RSAKeyjava.security.interfaces.RSAPublicKey接口。

注意:Android 密钥存储中存储的密钥的密钥材料不可访问。

此类的实例是不可变的。

<h3>已知问题</h3> Android 6.0(API 级别 23)中的已知 bug 会导致即使对公钥强制实施与用户身份验证相关的授权。 若要解决此问题,请提取公钥材料,以在 Android 密钥存储外部使用。 例如:

{@code
            PublicKey unrestrictedPublicKey =
                    KeyFactory.getInstance(publicKey.getAlgorithm()).generatePublic(
                            new X509EncodedKeySpec(publicKey.getEncoded()));
            }

<h3>示例:GCM 模式</h3 中用于加密/解密的 AES 密钥/h3> 演示了如何在授权仅用于 GCM 模式下的加密/解密的别名 key1 下将 AES 密钥导入 Android KeyStore,而无需填充。 密钥必须以Key#getEncoded()RAW格式导出其密钥材料。

{@code
            SecretKey key = ...; // AES key

            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            keyStore.setEntry(
                    "key1",
                    new KeyStore.SecretKeyEntry(key),
                    new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                            .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                            .build());
            // Key imported, obtain a reference to it.
            SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
            // The original key can now be discarded.

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

<h3>示例:用于使用 SHA-512/h3> 生成 MAC 的 HMAC 密钥此示例演示如何在授权仅用于使用 SHA-512< 摘要生成 MAC 的别名key1下将 HMAC 密钥导入 Android KeyStore。 密钥必须以Key#getEncoded()RAW格式导出其密钥材料。

{@code
            SecretKey key = ...; // HMAC key of algorithm "HmacSHA512".

            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            keyStore.setEntry(
                    "key1",
                    new KeyStore.SecretKeyEntry(key),
                    new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
            // Key imported, obtain a reference to it.
            SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
            // The original key can now be discarded.

            Mac mac = Mac.getInstance("HmacSHA512");
            mac.init(keyStoreKey);
            ...
            }

<h3>示例:使用 ECDSA</h3> 进行签名/验证的 EC 密钥对演示了如何使用 SHA-256 或 SHA-512 摘要将 EC 密钥对导入到别名 key2 下的 Android KeyStore 中。 公钥的使用不受限制。 私钥和公钥必须分别通过Key#getEncoded()PKCS#8X.509格式导出其密钥材料。

{@code
            PrivateKey privateKey = ...;   // EC private key
            Certificate[] certChain = ...; // Certificate chain with the first certificate
                                           // containing the corresponding EC public key.

            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            keyStore.setEntry(
                    "key2",
                    new KeyStore.PrivateKeyEntry(privateKey, certChain),
                    new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
                            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                            .build());
            // Key pair imported, obtain a reference to it.
            PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
            PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
            // The original private key can now be discarded.

            Signature signature = Signature.getInstance("SHA256withECDSA");
            signature.initSign(keyStorePrivateKey);
            ...
            }

<h3>示例:使用 PKCS#1 填充<进行签名/验证的 RSA 密钥对/h3> 演示了如何将 RSA 密钥对导入到别名 key2 下的 Android KeyStore 中,该密钥对的别名授权仅用于使用具有 SHA-256 摘要的 PKCS#1 签名填充方案进行签名,并且仅当用户在过去 10 分钟内进行身份验证。 公钥的使用不受限制(请参阅已知问题)。 私钥和公钥必须分别通过Key#getEncoded()PKCS#8X.509格式导出其密钥材料。

{@code
            PrivateKey privateKey = ...;   // RSA private key
            Certificate[] certChain = ...; // Certificate chain with the first certificate
                                           // containing the corresponding RSA public key.

            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            keyStore.setEntry(
                    "key2",
                    new KeyStore.PrivateKeyEntry(privateKey, certChain),
                    new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
                            .setDigests(KeyProperties.DIGEST_SHA256)
                            .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                            // Only permit this key to be used if the user
                            // authenticated within the last ten minutes.
                            .setUserAuthenticationRequired(true)
                            .setUserAuthenticationValidityDurationSeconds(10 * 60)
                            .build());
            // Key pair imported, obtain a reference to it.
            PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
            PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
            // The original private key can now be discarded.

            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(keyStorePrivateKey);
            ...
            }

<h3>示例:使用 PKCS#1 填充<进行加密/解密的 RSA 密钥对/h3> 此示例演示了如何使用 PKCS#1 加密填充方案将 RSA 密钥对导入到别名 key2 下的 Android KeyStore 中,私钥仅用于解密。 公钥的使用不受限制,因此允许使用任何填充方案和摘要进行加密。 私钥和公钥必须分别通过Key#getEncoded()PKCS#8X.509格式导出其密钥材料。

{@code
            PrivateKey privateKey = ...;   // RSA private key
            Certificate[] certChain = ...; // Certificate chain with the first certificate
                                           // containing the corresponding RSA public key.

            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            keyStore.setEntry(
                    "key2",
                    new KeyStore.PrivateKeyEntry(privateKey, certChain),
                    new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
                            .build());
            // Key pair imported, obtain a reference to it.
            PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
            PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
            // The original private key can now be discarded.

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, keyStorePrivateKey);
            ...
            }

适用于 . 的 android.security.keystore.KeyProtectionJava 文档

本页的某些部分是根据 Android 开放源代码项目创建和共享的工作进行的修改,并根据 Creative Commons 2.5 属性许可证中所述的术语使用。

属性

Class

返回此 Object的运行时类。

(继承自 Object)
Handle

基础 Android 实例的句柄。

(继承自 Object)
IsDigestsSpecified

返回 true 是否可以使用密钥的摘要算法集。

IsInvalidatedByBiometricEnrollment

返回 true 在注册新的生物识别或删除所有已注册生物识别时,密钥是否不可逆转地失效。

IsRandomizedEncryptionRequired

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

IsUnlockedDeviceRequired

如果 true 必须解锁屏幕,以便此密钥用于解密或签名。

IsUserAuthenticationRequired

如果 true 仅当用户已经过身份验证时,才授权使用该密钥。

IsUserAuthenticationValidWhileOnBody

true 从用户的正文中删除设备时,是否将取消授权密钥。

IsUserConfirmationRequired

如果 true 授权密钥仅用于用户确认的消息,则返回。

IsUserPresenceRequired

如果true仅当在和Signature.sign()调用之间Signature.initSign()执行用户状态测试时,才授权使用该密钥。

JniIdentityHashCode

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
JniPeerMembers

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

KeyValidityForConsumptionEnd

获取密钥在解密和验证后不再有效的时间。

KeyValidityForOriginationEnd

获取密钥对加密和签名无效的时间。

KeyValidityStart

获取密钥尚无效之前的时间。

MaxUsageCount

返回允许使用有限使用密钥的最大次数,或者 KeyProperties#UNRESTRICTED_USAGE_COUNT 对可以使用密钥的次数没有限制。

PeerReference

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
Purposes

获取目的集(e.

ThresholdClass

此 API 支持 Mono for Android 基础结构,不打算直接从代码使用。

(继承自 Object)
ThresholdType

此 API 支持 Mono for Android 基础结构,不打算直接从代码使用。

(继承自 Object)
UserAuthenticationType

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

UserAuthenticationValidityDurationSeconds

获取在用户成功进行身份验证后授权使用此密钥的时间(秒)。。

方法

Clone()

创建并返回此对象的副本。

(继承自 Object)
Dispose()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
Dispose(Boolean)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
Equals(Object)

指示其他对象是否“等于”此对象。

(继承自 Object)
GetBlockModes()

获取块模式集(e.

GetDigests()

获取摘要算法集(e.

GetEncryptionPaddings()

获取填充方案集(e.

GetHashCode()

返回对象的哈希代码值。

(继承自 Object)
GetSignaturePaddings()

获取填充方案集(e.

JavaFinalize()

当垃圾回收确定不再引用该对象时,由对象上的垃圾回收器调用。

(继承自 Object)
Notify()

唤醒正在等待此对象的监视器的单个线程。

(继承自 Object)
NotifyAll()

唤醒正在等待此对象的监视器的所有线程。

(继承自 Object)
SetHandle(IntPtr, JniHandleOwnership)

设置 Handle 属性。

(继承自 Object)
ToArray<T>()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
ToString()

返回对象的字符串表示形式。

(继承自 Object)
UnregisterFromRuntime()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
Wait()

使当前线程等待,直到唤醒它,通常是通过 em 通知/em> 或 <em>interrupted</em>。<><

(继承自 Object)
Wait(Int64)

使当前线程等待直到唤醒,通常是通过 <em>通知</em> 或 <em interrupted</em>>,或直到经过一定数量的实时。

(继承自 Object)
Wait(Int64, Int32)

使当前线程等待直到唤醒,通常是通过 <em>通知</em> 或 <em interrupted</em>>,或直到经过一定数量的实时。

(继承自 Object)

显式接口实现

IJavaPeerable.Disposed()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.DisposeUnlessReferenced()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.Finalized()

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.JniManagedPeerState

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

(继承自 Object)

扩展方法

JavaCast<TResult>(IJavaObject)

执行 Android 运行时检查的类型转换。

JavaCast<TResult>(IJavaObject)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

GetJniTypeName(IJavaPeerable)

指定在导入 Android 密钥存储系统时如何保护密钥或密钥对。

适用于