用戶端 SDK 3 的支援 Java 金錀屬性 - AWS CloudHSM

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

用戶端 SDK 3 的支援 Java 金錀屬性

本主題說明如何使用 Java 程式庫 3.1 版的專屬擴充功能來設定金鑰屬性。請在以下操作期間,使用此擴充功能來設定支援的金鑰屬性及其值:

  • 金鑰產生

  • 金鑰匯入

  • 金鑰取消包裝

注意

設定自訂金鑰屬性的擴充功能是選用功能。如果您具有在 Java 程式庫 3.0 版本中運作的程式碼,則不需要修改該程式碼。您建立的金鑰會繼續包含與之前相同的屬性。

了解屬性

您可以使用金鑰屬性來指定金鑰物件上允許的動作,包括公有金鑰、私有金鑰或秘密金鑰。您可以在建立金鑰物件操作期間定義金鑰屬性和值。

但是,Java Cryptography Extension (JCE) 未指定應該如何設定金鑰屬性的值,因此預設情況下會允許大部分動作。相反地,PKCS#11 標準定義了一組具有更嚴格預設值的完整屬性。從 Java 程式庫 3.1 版開始,CloudHSM 提供專屬的擴充功能,可讓您為常用的屬性設定更嚴格的值。

支援的屬性

您可以設定下表中列出之屬性的值。最佳實務是,只為您希望更具有限制性的屬性設定值。如果您未指定值,CloudHSM 會使用下表中指定的預設值。預設值欄位中的空白儲存格表示屬性沒有獲派指定預設值。

屬性 預設值 備註
對稱金鑰 金鑰對中的公有金鑰 金鑰對中的私有金鑰
CKA_TOKEN FALSE FALSE FALSE

永久金鑰,會跨叢集中的所有 HSM 進行複寫並包含在備份中。CKA_TOKEN = FALSE 代表工作階段金鑰,該金鑰只被載入到一個 HSM 上,並在與 HSM 的連接中斷時自動擦除。

CKA_LABEL 使用者定義的字串。它可讓您輕鬆識別 HSM 上的金鑰。
CKA_EXTRACTABLE TRUE TRUE True 表示您可以從 HSM 匯出此金鑰。
CKA_ENCRYPT TRUE TRUE True 表示您可以使用金鑰來加密任何緩衝區。
CKA_DECRYPT TRUE TRUE True 表示您可以使用金鑰來解密任何緩衝區。對於其 CKA_WRAP 設定為 true 的金鑰,通常將此設定為 FALSE。
CKA_WRAP TRUE TRUE True 表示您可以使用該金鑰來包裝另一個金鑰。對於私有金鑰,您通常將此設定為 FALSE。
CKA_UNWRAP TRUE TRUE True 表示您可以使用金鑰來取消包裝 (匯入) 另一個金鑰。
CKA_SIGN TRUE TRUE True 表示您可以使用金鑰來簽署訊息摘要。對於公有金鑰和您已封存的私有金鑰,這通常會設定為 FALSE。
CKA_VERIFY TRUE TRUE True 表示您可以使用金鑰來驗證簽章。對於私有金鑰,這通常被設定為 FALSE。
CKA_PRIVATE TRUE TRUE TRUE True 表示在使用者通過驗證之前,使用者可能無法存取金鑰。為了清楚起見,使用者在通過驗證之前無法存取 CloudHSM 上的任何金鑰,即使此屬性設為 FALSE 也一樣。
注意

您可以在 PKCS #11 程式庫中獲得更廣泛的屬性支援。如需詳細資訊,請參閱支援的 PKCS #11 屬性

設定金鑰的屬性

CloudHsmKeyAttributesMap 是類似 Java 映射的物件,您可以使用它來設定金鑰物件的屬性值。CloudHsmKeyAttributesMap 函數的方法類似於用於 Java 映射處理的方法。

若要設定屬性的自訂值,您有兩個選項:

  • 使用下表中列出的方法

  • 使用本文稍後示範的產生器模式

屬性映射物件支援以下列方法設定屬性:

作業 傳回值 CloudHSMKeyAttributesMap 方法
獲取現有金鑰的金鑰屬性的值 物件 (包含值) 或 null

get(keyAttribute)

填入一個金鑰屬性的值 與金鑰屬性相關聯的先前值,如果金鑰屬性沒有映射,則為 null

put(keyAttribute, value)

填入多個金鑰屬性的值 N/A

putAll () keyAttributesMap

從屬性映射中刪除金鑰值對

與金鑰屬性相關聯的先前值,如果金鑰屬性沒有映射,則為 null

remove(keyAttribute)

注意

您未明確指定的任何屬性都會設定為支援的屬性中上表所列的預設值。

產生器模式範例

開發人員通常會發現,透過產生器模式利用類別更加方便。舉例來說:

import com.amazonaws.cloudhsm.CloudHsmKeyAttributes; import com.amazonaws.cloudhsm.CloudHsmKeyAttributesMap; import com.amazonaws.cloudhsm.CloudHsmKeyPairAttributesMap; CloudHsmKeyAttributesMap keyAttributesSessionDecryptionKey = new CloudHsmKeyAttributesMap.Builder() .put(CloudHsmKeyAttributes.CKA_LABEL, "ExtractableSessionKeyEncryptDecrypt") .put(CloudHsmKeyAttributes.CKA_WRAP, false) .put(CloudHsmKeyAttributes.CKA_UNWRAP, false) .put(CloudHsmKeyAttributes.CKA_SIGN, false) .put(CloudHsmKeyAttributes.CKA_VERIFY, false) .build(); CloudHsmKeyAttributesMap keyAttributesTokenWrappingKey = new CloudHsmKeyAttributesMap.Builder() .put(CloudHsmKeyAttributes.CKA_LABEL, "TokenWrappingKey") .put(CloudHsmKeyAttributes.CKA_TOKEN, true) .put(CloudHsmKeyAttributes.CKA_ENCRYPT, false) .put(CloudHsmKeyAttributes.CKA_DECRYPT, false) .put(CloudHsmKeyAttributes.CKA_SIGN, false) .put(CloudHsmKeyAttributes.CKA_VERIFY, false) .build();

開發人員也可以利用預先定義的屬性集,作為在金鑰範本中強制執行最佳實務的便利方式。舉例來說:

//best practice template for wrapping keys CloudHsmKeyAttributesMap commonKeyAttrs = new CloudHsmKeyAttributesMap.Builder() .put(CloudHsmKeyAttributes.CKA_EXTRACTABLE, false) .put(CloudHsmKeyAttributes.CKA_DECRYPT, false) .build(); // initialize a new instance of CloudHsmKeyAttributesMap by copying commonKeyAttrs // but with an appropriate label CloudHsmKeyAttributesMap firstKeyAttrs = new CloudHsmKeyAttributesMap(commonKeyAttrs); firstKeyAttrs.put(CloudHsmKeyAttributes.CKA_LABEL, "key label"); // alternatively, putAll() will overwrite existing values to enforce conformance CloudHsmKeyAttributesMap secondKeyAttrs = new CloudHsmKeyAttributesMap(); secondKeyAttrs.put(CloudHsmKeyAttributes.CKA_DECRYPT, true); secondKeyAttrs.put(CloudHsmKeyAttributes.CKA_ENCRYPT, true); secondKeyAttrs.put(CloudHsmKeyAttributes.CKA_LABEL, “safe wrapping key”); secondKeyAttrs.putAll(commonKeyAttrs); // will overwrite CKA_DECRYPT to be FALSE

設定金鑰對的屬性

使用 Java 類別 CloudHsmKeyPairAttributesMap 來處理金鑰對的金鑰屬性。CloudHsmKeyPairAttributesMap 封裝了兩個 CloudHsmKeyAttributesMap 物件;一個用於公有金鑰,另一個用於私有金鑰。

若要分別為公有金鑰和私有金鑰設定個別屬性,您可以在該金鑰對應的 CloudHsmKeyAttributes 映射物件上使用 put() 方法。使用 getPublic() 方法來擷取公有金鑰的屬性映射,以及使用 getPrivate() 來擷取私有金鑰的屬性映射。使用 putAll() 與金鑰對屬性映射作為引數,填入公有金鑰和私有金鑰對的多個金鑰屬性值。

產生器模式範例

開發人員通常會發現,透過產生器模式來設定金鑰屬性更加方便。例如:

import com.amazonaws.cloudhsm.CloudHsmKeyAttributes; import com.amazonaws.cloudhsm.CloudHsmKeyAttributesMap; import com.amazonaws.cloudhsm.CloudHsmKeyPairAttributesMap; //specify attributes up-front CloudHsmKeyAttributesMap keyAttributes = new CloudHsmKeyAttributesMap.Builder() .put(CloudHsmKeyAttributes.CKA_SIGN, false) .put(CloudHsmKeyAttributes.CKA_LABEL, "PublicCertSerial12345") .build(); CloudHsmKeyPairAttributesMap keyPairAttributes = new CloudHsmKeyPairAttributesMap.Builder() .withPublic(keyAttributes) .withPrivate( new CloudHsmKeyAttributesMap.Builder() //or specify them inline .put(CloudHsmKeyAttributes.CKA_LABEL, "PrivateCertSerial12345") .put (CloudHSMKeyAttributes.CKA_WRAP, FALSE) .build() ) .build();
注意

如需有關此專屬延伸功能的詳細資訊,請參閱 Javadoc 封存檔和上的範例。 GitHub若要瀏覽 Javadoc,請下載並展開此封存。

整合練習

若要使用金鑰操作指定金鑰屬性,請依照下列步驟執行:

  1. 執行個體化對稱金鑰的 CloudHsmKeyAttributesMap 或金鑰對的 CloudHsmKeyPairAttributesMap

  2. 使用必要的金鑰屬性和值來定義步驟 1 的屬性物件。

  3. 執行個體化對應至特定金鑰類型的 Cavium*ParameterSpec 類別,並在其建構函數中傳遞此設定好的屬性物件。

  4. 將此 Cavium*ParameterSpec 物件傳遞到相應的加密類別或方法中。

如需參考,下表包含支援自定義金鑰屬性的 Cavium*ParameterSpec 類別和方法。

金鑰類型 參數規格類別 範例建構函數
基本類別 CaviumKeyGenAlgorithmParameterSpec CaviumKeyGenAlgorithmParameterSpec(CloudHsmKeyAttributesMap keyAttributesMap)
DES CaviumDESKeyGenParameterSpec CaviumDESKeyGenParameterSpec(int keySize, byte[] iv, CloudHsmKeyAttributesMap keyAttributesMap)
RSA CaviumRSAKeyGenParameterSpec CaviumRSAKeyGenParameterSpec(int keysize, BigInteger publicExponent, CloudHsmKeyPairAttributesMap keyPairAttributesMap)
秘密 CaviumGenericSecretKeyGenParameterSpec CaviumGenericSecretKeyGenParameterSpec(int size, CloudHsmKeyAttributesMap keyAttributesMap)
AES CaviumAESKeyGenParameterSpec CaviumAESKeyGenParameterSpec(int keySize, byte[] iv, CloudHsmKeyAttributesMap keyAttributesMap)
EC CaviumECGenParameterSpec CaviumECGenParameterSpec(String stdName, CloudHsmKeyPairAttributesMap keyPairAttributesMap)

範本程式碼:產生並包裝金鑰

這些簡短的程式碼範例示範兩個不同操作的步驟:金鑰產生和金鑰包裝:

// Set up the desired key attributes KeyGenerator keyGen = KeyGenerator.getInstance("AES", "Cavium"); CaviumAESKeyGenParameterSpec keyAttributes = new CaviumAESKeyGenParameterSpec( 256, new CloudHsmKeyAttributesMap.Builder() .put(CloudHsmKeyAttributes.CKA_LABEL, "MyPersistentAESKey") .put(CloudHsmKeyAttributes.CKA_EXTRACTABLE, true) .put(CloudHsmKeyAttributes.CKA_TOKEN, true) .build() ); // Assume we already have a handle to the myWrappingKey // Assume we already have the wrappedBytes to unwrap // Unwrap a key using Custom Key Attributes CaviumUnwrapParameterSpec unwrapSpec = new CaviumUnwrapParameterSpec(myInitializationVector, keyAttributes); Cipher unwrapCipher = Cipher.getInstance("AESWrap", "Cavium"); unwrapCipher.init(Cipher.UNWRAP_MODE, myWrappingKey, unwrapSpec); Key unwrappedKey = unwrapCipher.unwrap(wrappedBytes, "AES", Cipher.SECRET_KEY);