語言

KeyProtection 類別

定義

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

[Android.Runtime.Register("android/security/keystore/KeyProtection", ApiSince=23, DoNotGenerateAcw=true)]
public sealed class KeyProtection : Java.Lang.Object, IDisposable, 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 Keystore 系統時如何受到保護。 此類別規定匯入金鑰的授權用途,例如使用金鑰是否需要使用者驗證、金鑰被授權執行哪些操作(例如解密但不簽名)、參數(例如僅限特定填充方案或摘要)以及金鑰的有效開始與結束日期。 本類別中表達的金鑰使用授權僅適用於秘密金鑰與私鑰——公鑰可用於任何支援的操作。

要將金鑰或金鑰對匯入 Android Keystore,請使用 建立Builder此類別的實例,並將該實例與匯入的金鑰或金鑰對一同傳遞。java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry

若要從 Android Keystore 取得秘密/對稱或私密金鑰,請使用 java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null) 或 java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)。 要從 Android Keystore 取得公鑰,請使用 java.security.KeyStore#getCertificate(String) ,然後 Certificate#getPublicKey()。

為了幫助取得儲存在 Android Keystore 中的金鑰對的演算法專屬公開參數,其私鑰用於實作 java.security.interfaces.ECKey 或 java.security.interfaces.RSAKey 介面,而公鑰則用於實作 java.security.interfaces.ECPublicKey 或 java.security.interfaces.RSAPublicKey 介面。

注意:儲存在 Android Keystore 的金鑰材料無法存取。

此類別的實例是不可變的。

<h3>已知問題</h3> Android 6.0(API Level 23)中的一個已知錯誤,導致即使是公開金鑰也被強制執行與使用者驗證相關的授權。 為了解決這個問題,請將公開金鑰資料擷取到用於 Android Keystore 以外的資料。 例如:

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

<h3>範例:在 GCM 模式</h3> 中用於加密/解密的 AES 金鑰 此範例說明如何將 AES 金鑰匯入 Android KeyStore,授權該別名 key1 僅用於 GCM 模式下的加密/解密,且無填充。 該金鑰必須以 格式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 金鑰 此範例說明如何將 HMAC 金鑰匯入 Android KeyStore,並授權 key1 僅用於使用 SHA-512 摘要產生 MAC。 該金鑰必須以 格式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 金鑰對 本範例說明如何將 EC 金鑰對以別名 key2 方式匯入 Android KeyStore,私鑰僅授權用於 SHA-256 或 SHA-512 摘要的簽署。 公鑰的使用不受限制。 私鑰與公鑰都必須分別透過 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 填充</h3> 的簽署/驗證 RSA 金鑰對 本範例說明如何將 RSA 金鑰對以別名 key2 方式匯入 Android KeyStore,私鑰僅授權用於 PKCS#1 簽章填充方案與 SHA-256 摘要的簽署,且僅限於使用者在過去十分鐘內完成驗證。 公開金鑰的使用不受限制(參見已知問題)。 私鑰與公鑰都必須分別透過 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 填充</h3> 進行加密/解密的 RSA 金鑰對 本範例說明如何將 RSA 金鑰對以別名 key2 方式匯入 Android KeyStore,私鑰僅授權用於 PKCS#1 加密填充方案的解密。 公鑰的使用不受限制,因此允許使用任何填充方案和摘要進行加密。 私鑰與公鑰都必須分別透過 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);
            ...
            }

Java 文件 android.security.keystore.KeyProtection。

本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。

屬性

名稱 Description
Class

回傳此 Object的執行時類別。

(繼承來源 Object)
Handle

底層 Android 實例的帳號。

(繼承來源 Object)
IsDigestsSpecified

若指定可用於該金鑰的摘要演算法集合,則回傳 true 。

IsInvalidatedByBiometricEnrollment

若在新生物識別註冊或所有註冊生物識別資料被移除後,該金鑰不可逆轉地失效,則會退還 true 。

IsMgf1DigestsSpecified

true若指定可用於 MGF1 遮罩產生函數的消化集,則返回。

IsRandomizedEncryptionRequired

如果使用此金鑰加密,則返回 true 必須足夠隨機化,以每次產生相同明文的不同密文。

IsUnlockedDeviceRequired

若鑰匙被授權只能在裝置解鎖時使用,則會退貨 true 。

IsUserAuthenticationRequired

若金鑰被授權僅在使用者已認證時使用,則會回傳 true 。

IsUserAuthenticationValidWhileOnBody

如果裝置從使用者身上移除時,金鑰會被取消授權,則會回傳 true 。

IsUserConfirmationRequired

若金鑰被授權僅用於使用者確認的訊息,則會回傳 true 。

IsUserPresenceRequired

若金鑰被授權僅在 與 true 通話間Signature.initSign()測試使用者存在狀態時使用,則回傳Signature.sign()。

JniIdentityHashCode

取得由互通執行時指派給此 Java 對等端的身份雜湊碼。

(繼承來源 Object)
JniManagedPeerState

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
JniPeerMembers

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

KeyValidityForConsumptionEnd

取得時間瞬間,之後金鑰不再有效,無法進行解密和驗證。

KeyValidityForOriginationEnd

會立即獲得該金鑰不再有效用於加密和簽署的時間。

KeyValidityStart

取得金鑰尚未有效的時間。

MaxUsageCount

回傳有限使用金鑰允許使用的最大次數,或 KeyProperties#UNRESTRICTED_USAGE_COUNT 若金鑰使用次數無限制。

Mgf1Digests

回傳可由MGF1遮罩產生函數使用的消化集合(例如:

PeerReference

取得這個 Java 節點的 JNI 物件參考。

(繼承來源 Object)
Purposes

獲得目的集合(例如:

ThresholdClass

此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。

(繼承來源 Object)
ThresholdType

此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。

(繼承來源 Object)
UserAuthenticationType

取得一組可授權使用金鑰的認證類型。

UserAuthenticationValidityDurationSeconds

取得使用者成功認證後,該金鑰被授權使用的時間(秒數)。

方法

名稱 Description
Clone()

建立並回傳此物件的副本。

(繼承來源 Object)
Construct(JniObjectReference, JniObjectReferenceOptions)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
Dispose()

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
Dispose(Boolean)

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
DisposeUnlessReferenced()

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
Equals(Object)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
Equals(Object)

表示是否有其他物體「等同」於此物。

(繼承來源 Object)
GetBlockModes()

得到區塊模式集合(例如

GetDigests()

取得一組摘要演算法(例如

GetEncryptionPaddings()

得到一組填充方案(例如:

GetHashCode()

回傳物件的雜湊碼值。

(繼承來源 Object)
GetSignaturePaddings()

得到一組填充方案(例如:

JavaFinalize()
已淘汰.

當垃圾回收判定該物件不再有相關參考時,由垃圾回收器呼叫。

(繼承來源 Object)
Notify()

喚醒一個正在該物件監視器上等待的執行緒。

(繼承來源 Object)
NotifyAll()

喚醒所有等待該物件監視器的執行緒。

(繼承來源 Object)
SetHandle(IntPtr, JniHandleOwnership)

設定 Handle 屬性。

(繼承來源 Object)
SetPeerReference(JniObjectReference, JniObjectReferenceOptions)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
ToArray<T>()

從這個 Java 陣列包裝器建立一個受管理陣列。

(繼承來源 Object)
ToString()

回傳物件的字串表示。

(繼承來源 Object)
UnregisterFromRuntime()

將此 Java 節點從互通執行時中取消註冊。

(繼承來源 Object)
Wait()

導致目前執行緒等待被喚醒,通常是透過 <em>通知</><em 或 em>中斷</em> 來喚醒。

(繼承來源 Object)
Wait(Int64, Int32)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)
Wait(Int64)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)

明確介面實作

名稱 Description
IJavaPeerable.Disposed()

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.Finalized()

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.JniObjectReferenceControlBlock

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.SetJniIdentityHashCode(Int32)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.SetPeerReference(JniObjectReference)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

(繼承來源 JavaObject)
IJavaPeerable.UnregisterFromRuntime()

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

擴充方法

名稱 Description
GetJniTypeName(IJavaPeerable)

取得實例 self類型的 JNI 名稱。

JavaAs<TResult>(IJavaPeerable)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

JavaCast<TResult>(IJavaObject)

執行 Android 執行時檢查型別轉換。

JavaCast<TResult>(IJavaObject)

規範將金鑰或金鑰對匯入 Android Keystore 系統時如何受到保護。

TryJavaCast<TResult>(IJavaPeerable, TResult)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

適用於