Data Encryption Service為您提供密碼機執行個體叢集功能,實現將處於同一地區不同可用性區域、用於相同業務的一組密碼機執行個體關聯起來,應用程式可以基於特定的輪詢演算法選取合適的密碼機,使用同一個密鑰執行密碼運算操作,為業務應用提供商務持續性、密碼計算的高可用性、負載平衡以及橫向擴充的能力。本文介紹如何使用密碼機執行個體叢集。
如果您需要建立KMS硬體密鑰管理執行個體的密碼機叢集,請參見配置KMS硬體密鑰管理執行個體的密碼機叢集。
叢集同步方式說明
叢集同步是將主密碼機的密鑰、配置的SSL認證以及使用者資訊等,同步到子密碼機。叢集同步方式與密碼機的購買時間有關:
2025年01月09日及之後購買的密碼機:建立叢集後叢集同步方式預設為自動同步,主密碼機資料變更後您無需手動同步叢集資料。
2025年01月09日之前購買的密碼機:建立叢集後資料同步方式預設為手動同步,即主密碼機資料變更後需要您手動執行同步叢集操作。如果您需要將叢集升級為自動同步,請聯絡我們。
警告升級後不支援回退,升級過程中可能存在以下風險,建議您在業務低峰期升級。
配套使用阿里雲KMS硬體密鑰管理執行個體的使用者:
管控類操作:升級時不支援建立密鑰、刪除密鑰等管控類操作,升級完成後自動回復。
業務類操作:升級時加解密等業務類操作不受影響。
其他使用者:需要您配合升級應用所依賴的密碼機SDK版本。
管控類操作:升級時不支援建立密鑰、刪除密鑰等管控類操作,升級完成後自動回復。
業務類操作:部分業務架構下,升級時可能存在業務中斷風險。
前提條件
-
已購買密碼機。具體操作,請參見購買密碼機。
-
已購買Windows系統的ECS執行個體,且ECS執行個體需要和密碼機執行個體在同一VPC。具體操作,請參見Windows系統執行個體快速入門。
說明該ECS執行個體用於安裝密碼機管理工具,而非用於商務服務器。
步驟一:建立並啟用叢集
一個叢集包括一個主密碼機與若干個子密碼機,同一叢集內所有密碼機必須屬於同一VPC,可以屬於同一或不同子網。
如果您購買GVSM(國密)配置了叢集資訊,HSM會根據您配置的叢集資訊自動建立叢集,請跳過本步驟。
啟用主密碼機執行個體。
-
訪問Data Encryption Service控制台的虛擬密碼機執行個體頁面,在頂部功能表列,選擇目標地區。
-
在虛擬密碼機執行個體頁面,定位到已建立的密碼機執行個體,單擊操作列的啟用。
-
在密碼機執行個體配置對話方塊,配置密碼機執行個體,然後單擊確定。配置成功後,密碼機執行個體的狀態變為已啟用。
配置項
說明
所屬的VPC網路ID
選擇密碼機執行個體需要綁定的VPC。
重要需要與您的ECS執行個體綁定的VPC是同一個。
所屬的VPC子網
選擇密碼機執行個體所屬的VPC子網網段。
分配私網IP地址
為密碼機執行個體分配一個私網IP地址。
重要-
私網IP地址必須是所屬的VPC子網網段中的IP地址,否則配置將會失敗。
-
末位為253、254、255的IP地址為系統保留地址,請勿使用。
設定密碼機執行個體白名單
設定訪問該密碼機執行個體的白名單。您可以輸入單個IP地址或網段地址,每行輸入1條資料,最多可以輸入10條資料。
-
未設定白名單:所有IP地址都能訪問密碼機執行個體。
-
設定了白名單:僅支援白名單內的訪問請求,不在白名單內的訪問請求將被拒絕。
重要-
如果您建立了叢集並設定了叢集的白名單,那麼叢集的白名單優先順序高於叢集中密碼機執行個體的白名單。
例如,叢集中密碼機執行個體的白名單為10.10.10.10,叢集的白名單為172.16.0.1,則您只能通過172.16.0.1訪問叢集中的密碼機執行個體。
-
不支援配置為0.0.0.0/0(允許存取所有來源IP)。
基於安全考慮,不推薦您允許存取所有來源IP。如果因臨時測試等原因確實需要允許存取所有來源IP,不配置白名單即可。
-
-
建立密碼機叢集。
定位到主密碼機執行個體,單擊操作列的建立叢集。
在建立並啟用叢集面板,建立叢集資訊。
配置項
說明
叢集名稱
自訂叢集的名稱。名稱不能重複且長度不允許超過24個字元。
設定叢集訪問白名單
允許訪問叢集的IP地址。如果未設定白名單,則所有IP地址都能訪問叢集,如果設定了白名單,則不在白名單內的訪問請求將被拒絕。
您可以輸入單個IP地址或網段地址,每行輸入1條資料,最多可以輸入10條資料。
重要-
叢集的白名單優先順序高於叢集中密碼機執行個體的白名單。例如,您設定的叢集中密碼機執行個體的白名單為10.10.10.10,叢集的白名單為172.16.0.1,則您只能通過172.16.0.1訪問叢集中的密碼機執行個體。
-
不支援配置為0.0.0.0/0(允許存取所有來源IP)。
基於安全考慮,不推薦您允許存取所有來源IP。如果因臨時測試等原因確實需要允許存取所有來源IP,不配置白名單即可。
指定叢集的交換器(2~4個)
根據業務需要選擇可用性區域的交換器。
在密碼機執行個體叢集中,您至少配置2個交換器才能成功建立並啟用叢集。
-
初始化密碼機執行個體,然後單擊下一步。
說明只有主密碼機狀態為已初始化時才能啟用叢集。
初始化方式
操作步驟
方式一:在Data Encryption Service控制台一鍵初始化
重要使用一鍵初始化,您的密碼機必須是通用密碼機GVSM且您沒有使用UKEY的需求。
-
在建立並啟用叢集面板的最下方,單擊一鍵初始化主密碼機執行個體。
-
在初始化執行個體對話方塊,單擊確定。
初始化預計需要1~5分鐘時間,請耐心等待。初始化完成後,單擊已選主密碼機:後的
表徵圖,狀態會顯示已初始化,該狀態下請勿重複初始化。方式二:使用密碼機執行個體管理工具初始化
重要密碼機用戶端管理工具只支援在Windows系統運行。
在建立並啟用叢集面板的最下方,單擊下載密碼機執行個體管理工具。
解壓擷取密碼機軟體包,參考密碼機軟體包中的使用者管理手冊的《原始初始化》章節,完成初始化操作。
-
根據頁面提示,添加子密碼機到叢集,然後單擊完成。
(可選)步驟二:產生認證並配置TLS雙向認證
購買密碼機-HSM自動產生認證
僅GVSM(國密)支援在購買密碼機時選擇自動產生認證,此時HSM會自動產生認證,您只需在用戶端SDK側配置認證,HSM會自動在服務端加密機內部署認證。
在用戶端部署認證。
請在控制台下載用戶端認證,並自行部署至您的用戶端。
請在密碼機詳情頁面,單擊擷取叢集認證。在下載的檔案夾中包含下列檔案:
certs/ ├── client.p12 (PKCS12格式用戶端認證,包含用戶端認證以及私密金鑰) ├── client.pem (PEM格式用戶端認證) ├── rootca.key (CA私密金鑰) ├── rootca.pem (PEM格式CA認證) ├── server.p12 (PKCS12格式服務端認證) └── passphrase (PKCS12格式認證(尾碼為.p12)的認證保護口令)請將client.p12、rootca.pem部署至用戶端,同時用戶端設定檔中需要配置client.p12、rootca.pem的檔案路徑以及passphrase值。詳細介紹,請參見控制台下載的軟體包中的參考文檔。
在服務端部署認證。
HSM會自動將認證部署至密碼機,您無需關注。
認證的有效期間預設為10年,到期前HSM會自動產生認證並輪轉服務端認證,建議您不要使用密碼機管理工具建立UKEY管理員,建立UKEY管理員會導致認證輪轉失敗。
購買密碼機-HSM不自動產生認證
GVSM(國密)支援由HSM自動產生認證,但如果您在購買時未配置自動產生認證,參考如下步驟產生並部署認證。
產生認證。
將下載的檔案解壓後,運行認證檔案產生工具產生CA認證、用戶端認證和服務端認證。
說明工具的運行環境沒有限制,可以是本機電腦、ECS執行個體或其他滿足工具運行條件的環境。
工具僅為阿里雲提供的輔助性工具,如果您有相關技術能力可以自己產生這些認證檔案,則無需使用本工具。
Windows系統
方式一:在Windows檔案夾,雙擊滑鼠左鍵運行hsm_certificate_generate.exe檔案,在certs檔案夾擷取認證檔案。
說明該方式產生的PKCS12格式認證檔案(尾碼為.p12)和CA私密金鑰檔案(尾碼為.key)的口令為預設值12345678,如果您需要指定口令,請使用方式二。
方式二:切換到Windows檔案夾所在路徑,然後運行以下命令,在certs檔案夾擷取認證檔案。
./hsm_certificate_generate -dir ./certs -pswd 12345678-dir用於指定產生認證檔案的儲存路徑,-pswd用於指定產生的PKCS12格式認證檔案(尾碼為.p12)和CA私密金鑰檔案(尾碼為.key)的口令。
Linux系統
切換到Linux檔案夾所在路徑,然後運行以下命令,在certs檔案夾擷取認證檔案。
./hsm_certificate_generate -dir ./certs -pswd 12345678-dir用於指定產生認證檔案的儲存路徑,-pswd用於指定產生的PKCS12格式認證檔案(尾碼為.p12)和CA私密金鑰檔案(尾碼為.key)的口令。macOS系統
切換到darwin檔案夾所在路徑,然後運行以下命令,在certs檔案夾擷取認證檔案。
./hsm_certificate_generate -dir ./certs -pswd 12345678-dir用於指定產生認證檔案的儲存路徑,-pswd用於指定產生的PKCS12格式認證檔案(尾碼為.p12)和CA私密金鑰檔案(尾碼為.key)的口令。運行成功後,將在certs檔案夾中產生下列檔案:
certs/ ├── client.p12 (PKCS12格式用戶端認證,包含用戶端認證以及私密金鑰) ├── client.pem (PEM格式用戶端認證) ├── rootca.key (CA私密金鑰) ├── rootca.pem (PEM格式CA認證) ├── server.p12 (PKCS12格式服務端認證) └── server.pem (PEM格式服務端認證)
在用戶端部署認證。
請將client.p12、rootca.pem部署至用戶端,同時用戶端設定檔中需要配置client.p12、rootca.pem的檔案路徑以及您產生認證時輸入的口令。詳細介紹,請參見控制台下載的軟體包中的參考文檔。
在服務端部署認證。
在ECS執行個體上安裝密碼機執行個體管理工具。
重要密碼機執行個體管理工具只支援在Windows系統運行。
單擊主密碼機執行個體的規格列的
表徵圖,下載密碼機執行個體管理工具。解壓擷取到的密碼機軟體包,找到
PKIManager-X.X.X.X.exe然後上傳到ECS執行個體上。具體操作,請參見使用遠端桌面或Windows APP向Windows執行個體傳輸檔案。
使用密碼機執行個體管理工具配置主密碼機。
在ECS執行個體上使用密碼機執行個體管理工具串連主密碼機GVSM。
雙擊
PKIManager-X.X.X.X.exe開啟密碼機執行個體管理工具,選擇系統>TCP/IP串連。在TCP/IP串連對話方塊,輸入主密碼機的IP地址和連接埠號碼(固定為8020)。
IP地址請在控制台此處查看。主密碼機的IP地址可在密碼機執行個體列表的IP地址列中擷取,對應叢集列顯示為主密碼機的執行個體。
單擊串連,在彈出的PKIManager對話方塊單擊確定,然後單擊登入。
說明登入成功後,建議您註冊管理員帳號,使用管理員帳號登入以獲得更高的安全性。具體操作,請參見隨密碼機執行個體管理工具下載的GVSM使用者管理手冊中的2.1.3. 註冊管理員、2.1.2. 管理員登入。
使用密碼機執行個體管理工具完成如下配置。
配置項
操作步驟
配置用戶端認證(
client.pem)選擇密鑰管理>用戶端管理。
在用戶端認證管理對話方塊,單擊匯入認證。
在匯入認證對話方塊,認證類型選擇國際TLS用戶端RSA認證[pem],然後選擇認證檔案產生工具產生的用戶端認證(
client.pem),單擊匯入。
佈建服務端認證(
server.p12)選擇執行個體監控資訊>服務端管理。
在服務端p12認證管理對話方塊,單擊匯入認證。
在匯入認證對話方塊,認證類型選擇國際TLS服務端RSA認證[p12],然後選擇認證檔案產生工具產生的服務端認證(
server.p12),輸入認證口令(即您在產生認證檔案時設定的口令,如果您未設定,預設為12345678)。單擊匯入。
配置主密碼機GVSM裝置連接埠屬性
選擇。
在主機連接埠屬性對話方塊,配置以下參數:
Socket KeepAlive時間:60。
訊息報文頭長度:0。
訊息報文編碼格式:ASCII。
主機服務通訊方式:雙向通訊。
主機服務通訊協議:TLSv1.2。
單擊重設。
單擊立即重啟,然後單擊確定。
步驟三:同步叢集資料
當叢集類型為手動同步叢集時:第一次建立並啟用叢集後或者主密碼機資料變更後,都需要執行同步叢集操作,擴充叢集時無需同步叢集。
當叢集類型為自動同步叢集時:無需同步叢集,主密碼機新建立的密鑰、配置的SSL認證以及使用者資訊等,都會自動同步到子密碼機上。
同步叢集預計需要5分鐘,請在業務空閑期進行同步,以免影響業務運行。
在虛擬密碼機執行個體頁面,找到目標主密碼機執行個體,在執行個體列表的叢集類型列查看同步類型(手動同步叢集/自動同步叢集)。
當叢集類型為手動同步叢集時,執行同步叢集操作。
在操作列單擊同步叢集,在彈出的對話方塊中,再次單擊同步叢集。
步驟四:建立密鑰並使用密鑰加解密
在密碼機軟體包中找到密碼機的開發手冊、SDK測試程式等,您可以參考開發手冊,調用API介面使用密碼機執行個體。
您可以在Data Encryption Service控制台的虛擬密碼機執行個體頁面,單擊目標密碼機執行個體的規格列,下載密碼機執行個體管理工具 ,解壓後即得到密碼機軟體包。
以通用密碼機GVSM為例,在解壓後的阿里雲Data Encryption ServiceGVSM軟體包>SDK>JAVA>伺服器密碼機介面資料>測試demo目錄中找到測試案例《APITest.java》,使用該測試案例來測試密碼機執行個體。程式碼範例如下:
您需要將用例中的IP地址(192.168.XX.XX)修改為密碼機執行個體分配的私網IP地址。
package cn.tass.hsm;
import cn.tass.SJJ1507.devices.RasKeyUtils;
import cn.tass.common.kits.Padding;
import cn.tass.exceptions.TAException;
import cn.tass.hsm.GHSMAPI;
import cn.tass.kits.Forms;
import cn.tass.hsm.Host;
import cn.tass.hsm.LogConfig;
import cn.tass.util.encoders.Base64;
import org.junit.Test;
import javax.naming.ConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class APITest {
LogConfig logConfig = new LogConfig("error", "./");
Host host1 = new Host("GHSM", -3, "192.168.XX.XX", 8019, 5);
List<Host> hosts = new ArrayList<Host>() {{
add(host1);
}};
String config =
"{"
+ "[LOGGER];"
+ "logsw=debug,error;logPath=./;"
+ "[HOST 1];"
+ "hsmModel=GHSM;"
+ "host=192.168.XX.XX;linkNum=-3;"
+ "port=8019;"
+ "timeout=5;"
+ "}";
// GHSMAPI api = GHSMAPI.getInstance(hosts, logConfig);
GHSMAPI api = GHSMAPI.getInstance(config);
/**
* LMK加密的對稱金鑰
*/
byte[] symmetricKey = Forms.hexStringToByteArray("669C1CEDDA****5D727EA727558B5");
byte[] verifyValue = Forms.hexStringToByteArray("BD85****4D88");
byte[] symmetricKey1 = Forms.hexStringToByteArray("93EF12C958****C3EFDBC7B37642D");
byte[] verifyValue1 = Forms.hexStringToByteArray("7830****B8E6");
/**
* LMK加密的工作階段金鑰密文
*/
byte[] symmetricKeyKEK = Forms.hexStringToByteArray("2E80A42018****CF639F644629E8");
/**
* 工作階段金鑰的校正值
*/
byte[] verifyValueMAC = Forms.hexStringToByteArray("734D****3E38");
/**
* 保護密鑰保護的密文
*/
byte[] protectionKey = Forms.hexStringToByteArray("2EACE685C5EB2638D120*****CD44210B43C894A77C");
/**
* 保護密鑰保護的密文的MAC
*/
byte[] protectionMAC = Forms.hexStringToByteArray("0CB8****E487");
/**
* RSA DER編碼的公開金鑰
*/
byte[] publicKeyRSA = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E********1299BDBC17690C8E70F7BFA10EA02450805DA4C6CDC38BFBF1349C95B81A88177BA31C08")
* RSA LMK加密的私密金鑰
*/
byte[] privateKeyRSA = Forms.hexStringToByteArray("00202703D0652C7027B7D94B45A896646A9*********1B3CC00E37BE933055D5C00E37BE933055D54718ADDAA677519BD9C054CA249B43888")
/**
* RSA 保護祕密金鑰加密的私密金鑰
*/
byte[] privateKeyRSAKEK = Forms.hexStringToByteArray("6B2FB2BCC75604ABF5761FFA1027FF16324*********63AD3B57BD89059D5799974B4E5E9453763D94E682C629C4617C4E5393E9DDBFB")
/**
* RSA MAC
*/
byte[] privateKeyRSAKEKMAC = Forms.hexStringToByteArray("701A****9760");
/**
* KEK 加密的RSA私密金鑰
*/
byte[] privateKeyKEK = Forms.hexStringToByteArray("7A833CC0FAFBA6EC063DF4827B8FD91FF4B9A69F********1E02C312ABFC68F454D11EFCF1E0609584D06B09A08599D7A0BF5D63BB9F");
/**
* KEK RSA 私密金鑰MAC
*/
byte[] privateKeyRSAMAC = Forms.hexStringToByteArray("06E5****36DE");
/**
* KEK 加密的SM2私密金鑰
*/
byte[] privateKeySM2KEK = Forms.hexStringToByteArray("D3C5F579038C8BF34698****EF6044210B43C894A77C");
/**
* KEK SM2 私密金鑰MAC
*/
byte[] privateKeySM2MAC = Forms.hexStringToByteArray("83E4****0D15");
/**
* SM2 der編碼的公開金鑰
*/
byte[] privateKeySM2DER = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********42A53790967A1368B7084F6EFED51FC848D1E3B5370A99BDCB64D17C2F");
/**
* SM2 lmk加密的私密金鑰
*/
byte[] privateKeySM2 = Forms.hexStringToByteArray("66C9DDB0D6400EE05947****21908C4F5CA6457B435F");
/**
* SM2 保護密鑰保護的私密金鑰
*/
byte[] privateKeyKEKSM2 = Forms.hexStringToByteArray("D3C5F579038C8BF3A162****F99644210B43C894A77C");
/**
* SM2 MAC
*/
byte[] privateKeyKEKSM2MAC = Forms.hexStringToByteArray("B982****8232");
/**
* 隨機產生的sm2密鑰 1002
*/
byte[] publicSM2 = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********6913D902C4C9B8A84A3F96ADDD7BEF537D61404D56E58A68C756AEFD40");
byte[] privateSM2 = Forms.hexStringToByteArray("6F26783DCE6D45B84D3F****2FA68D1A3B721C09BB28");
/**
* MD5 演算法算出的資料摘要
*/
byte[] md5 = Forms.hexStringToByte("D41D8CD98F00B204E9800998ECF8427E");
/**
* SM3 演算法算出的資料摘要
*/
byte[] sm3 = Forms.hexStringToByte("E559D3DE421E81967DD68B28B55E0C26B03FCE10B8A8E5C4E6067497729D40D3");
/**
*
*/
byte[] b = Forms.hexStringToByteArray("00000000000000000000000000000000");
public APITest() throws TAException, ConfigurationException {
}
/**
* 產生對稱金鑰
*
* @throws TAException
*/
@Test
public void genSymmKey() throws TAException {
ArrayList<byte[]> bytes = api.genSymmKey(3);
System.out.println("LMK加密的對稱金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("對稱金鑰的校正值:" + Forms.byteToHexString(bytes.get(1)));
}
///////////////////////////////////////////////////////////////////////////
// 1015 測試資料
///////////////////////////////////////////////////////////////////////////
byte[] sm4Key = Forms.hexStringToByte("EE828FCCFA****468B1FECCE81192");
byte[] sm4CV = Forms.hexStringToByte("BCC2****2764");
byte[] sm4ProKeyCipher = Forms.hexStringToByte("7C78B0D533****E9277504181C23F");
byte[] sm4ProKeyCipherCV = Forms.hexStringToByte("8849****FB73");
byte[] newSM4 = Forms.hexStringToByte("AE62E4E90F****AECE0AC9923B885");
byte[] newSM4KeyMAC = Forms.hexStringToByte("F7EBEA9FD3****4E7EAAC9B7BE362");
byte[] newSM4KeyTag = Forms.hexStringToByte("7C05A01A54****E0C8597DBED6D6D");
byte[] sm4Key2 = Forms.hexStringToByte("40F7B1FA35****EB13491B119A4AB");
byte[] sm4Key2CV = Forms.hexStringToByte("955C****9C51");
/**
* 產生對稱金鑰,保護密鑰保護輸出
*
* @throws TAException
*/
@Test
public void generateProtectionKey() throws TAException {
/**
* sm4
* LMK加密的對稱金鑰:B36847D6E8****4EEB65558A2626C
* 對稱金鑰的校正值:713C****2AAB
*/
ArrayList<byte[]> bytes = api.proGenSymmKey(Forms.hexStringToByteArray("B36847D6E8****4EEB65558A2626C"),
TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("713C****2AAB"), TACryptConst.KEY_ALG_SM4, b,
TACryptConst.ENC_MODE_GCM,b, b);
System.out.println("LMK加密的工作階段金鑰密文:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("工作階段金鑰的校正值:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("保護祕密金鑰加密的工作階段金鑰密文:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("工作階段金鑰的MAC值:" + Forms.byteToHexString(bytes.get(3)));
System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));
}
/**
* 對稱金鑰加解密資料
*
* @throws TAException
*/
@Test
public void generalDataEnc() throws TAException {
// byte[] bytes = api.symmKeyDataEnc(sm4Key,TACryptConst.ENC_MODE_ECB,TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_SM4,
// "0000000000000000".getBytes(), b);
// System.out.println("SM4加密結果:" + Forms.byteToHexString(bytes));
// byte[] bytes1 = api.generalDataDec(sm4Key,TACryptConst.ENC_MODE_ECB, TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_SM4, bytes, b);
// System.out.println("SM4解密結果:" + new String(bytes1));
// byte[] paddingData = Padding.PKCS5Padding(Forms.hexStringToByte("30820122300D06092A864886F70D010101050003********FE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001"), 16);
// byte[] bytes = api.symmKeyDataEnc(28,TACryptConst.ENC_MODE_CBC,TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_AES128,
// paddingData, b);
// System.out.println("AES加密結果:" + Forms.byteToHexString(bytes));
byte[] bytes1 = api.generalDataDec(Forms.hexStringToByte("789F01F9CC****429D7EAB215ABA1"),TACryptConst.ENC_MODE_CBC, TACryptConst.KEY_TYPE_RULE, TACryptConst.KEY_ALG_AES128,
Forms.hexStringToByte("AE6BA9133D0D4BB0090882E33F03D905D7797852********B1C0079352310E974EB1155A759374004095E2256B0ADC3BFFFF150AF071"), b);
System.out.println("AES解密結果:" + Forms.byteToHexString(bytes1));
}
/**
* 對稱金鑰(受保護密鑰保護)加解密資料
*
* @throws TAException
*/
@Test
public void protectionKeyEncrypt() throws TAException {
ArrayList<byte[]> bytes = api.proKeyEncData(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV,
Forms.hexStringToByte("C0C64CD82E3B2DC8C8F4****F5BA4F0BCF7AC04E08E8"),
b, Forms.hexStringToByte("75F2C068A5****F0BCF7AC04E08E8"), TACryptConst.ENC_MODE_CBC,
b, new byte[0], new byte[0], TACryptConst.KEY_ALG_AES256, 1, 3,
new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
"mingwenshuju".getBytes(), new byte[12], new byte[2]);
System.out.println("密文: " + Forms.byteToHexString(bytes.get(0)));
System.out.println("tag: " + Forms.byteToHexString(bytes.get(1)));
byte[] bytes1 = api.proKeyDecData(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, Forms.hexStringToByte("C0C64CD82E3B2DC8C8F4****F5BA4F0BCF7AC04E08E8"), b, Forms.hexStringToByte("75F2C068A5****F0BCF7AC04E08E8"), TACryptConst.ENC_MODE_CBC,
b, new byte[0], new byte[0], TACryptConst.KEY_ALG_AES256, 1, 3, new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
bytes.get(0), new byte[12], new byte[2], bytes.get(1));
System.out.println("解密後的資料明文:" + new String(bytes1));
}
byte[] srcRSACipher = Forms.hexStringToByte("83E265207D4566C7704DF9E6170181378CA028FB********508F919F4C0B3F2F7C0B79E661001B79FB0F0205A97CECFBE25DC4C711EA");
byte[] srcRSACipherMAC = Forms.hexStringToByte("948D994479****72E54468349B3E5");
byte[] srcRSACipherTag = Forms.hexStringToByte("9C8A7CB4C6****75F0681ED497EDF");
byte[] srcRSApublicKey = Forms.hexStringToByteArray("308186028180E14CAAFFCEC6D014457D7CA3E943********BE8B795E10474954FE01BAAC63532520069465FA62EDB266AADEBB020103");
/**
* RSA LMK加密的私密金鑰
*/
byte[] srcRSAprivateKey = Forms.hexStringToByteArray("000202703D0652C7027B7D94B45A896646A9DC7C********571BC7CE29B67920538D509C58B1D8F966AF7E5321CDB2386164844D2BCB");
byte[] srcSM2Cipher = Forms.hexStringToByte("83E260209C09CEF21E1A****0B8D670537112DFB030F");
byte[] srcSM2CipherMAC = Forms.hexStringToByte("7DF725131F****F029550F2F073E9");
byte[] srcSM2CipherTag = Forms.hexStringToByte("A2181C5822****E37C072987D1B7E");
byte[] srcSM2publicKey = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********F8D3F9E5A31C7DE80940637E036B2D6FD36A0F586D4CDC3A610A269E89");
byte[] srcSM2privateKey = Forms.hexStringToByteArray("79E62264C314D1D3279D****F2BC777F8CBE7EC55699");
/**
* 巨量資料包加解密
*/
@Test
public void bigDataEnc() throws TAException {
byte[] enc = api.bigDataEnc(Forms.hexStringToByteArray("6DF7292D86****81F7C94DDC967A0"), "AES/ECB/PKCS5Padding", "demaxiyazhili".getBytes(), new byte[0]);
System.out.println(Forms.byteToHexString(enc));
byte[] dec = api.bigDataDec(Forms.hexStringToByteArray("6DF7292D86****81F7C94DDC967A0"), "AES/ECB/PKCS5Padding", enc, new byte[0]);
System.out.println(new String(dec));
}
/**
* 計算MAC、校正Mac
*/
@Test
public void mac() throws TAException {
byte[] bytes = api.calMac(1, 0, 2, sm4Key, 7, "1111111111111111".getBytes(),
new byte[16]);
System.out.println("計算MAC結果:" + Forms.byteToHexString(bytes));
boolean b = api.verifyMAC(1, 0, 2, sm4Key, 7, "1111111111111111".getBytes(),
new byte[16], bytes);
System.out.println("校正MAC結果:" + b);
}
/**
* 計算HMAC
*/
@Test
public void hmac() throws TAException {
ArrayList<byte[]> hmac = api.hmac(20, 0, 2, sm4Key, new byte[0], "shuyaojisuandeshuju".getBytes());
for (int i = 0; i < hmac.size(); i++) {
System.out.println(Forms.byteToHexString(hmac.get(i)));
}
}
/**
* 產生RSA演算法金鑰組,私密金鑰由LMK加密輸出
*/
@Test
public void generateRSAKeyPair() throws TAException, IOException {
ArrayList<byte[]> bytes = api.genRSAKey(2048, 65537);
System.out.println("DER編碼的公開金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("LMK加密的私密金鑰:" + Forms.byteToHexString(bytes.get(1)));
}
/**
* 產生RSA金鑰組,保護祕密金鑰加密輸出
*/
@Test
public void protectionKeyRSA() throws TAException, IOException {
ArrayList<byte[]> bytes = api.proGenRSAKey (sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, 2048, 3,
b, TACryptConst.ENC_MODE_ECB, b, new byte[2]);
System.out.println("DER編碼的公開金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("LMK加密的私密金鑰:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("保護祕密金鑰加密私密金鑰的密文:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("非對稱私密金鑰MAC的長度:" + Forms.byteToHexString(bytes.get(3)));
}
/**
* RSA 私密金鑰簽名 驗簽
*/
byte[] privateRSA = Forms.hexStringToByte("000204B07672172F114E8E847A5FB9EC3DD32CD1********AE837EB0B233D98470234F3EAD29C2DAB368CF5463151BCB266DEF496D8E");
byte[] publicRSA = Forms.hexStringToByte("3082010902820100EED2CF3C2E3624D65718E0F1********556D927F5DA9529C22D5C701B8B1BB7836D351A815A69116110203010001");
byte[] publicR77 = Forms.hexStringToByte("3082010A0282010100A636C484374F9F039EB431********FE2D80A275BF5D096D2E07BA9ED5A75A10D425B03B84BB57990203010001");
@Test
public void RSApriSign() throws TAException, IOException {
byte[] bytes = api.RSAPriKeySign(privateRSA,TACryptConst.PADDING_MODE_NO, 4, 0,
0, 0, Forms.hexStringToByte("9ECA5459BA0B5CA0****55E9DC2B6FFA85CE"));
System.out.println("簽名結果:" + Forms.byteToHexString(bytes));
boolean b = api.RSAPubVerify(publicRSA,TACryptConst.PADDING_MODE_PKCS15, TACryptConst.DIGEST_ALG_SHA256, 0,
0, 0, bytes, Forms.hexStringToByte("9ECA5459BA0B5CA0****55E9DC2B6FFA85CE"));
System.out.println("驗簽結果:" + b);
// ArrayList<byte[]> bytes1 = RasKeyUtils.loadDerRsaPublicKey(publicR77);
// for (int i = 0; i < bytes1.size(); i++) {
// System.out.println(Forms.byteToHexString(bytes1.get(i)));
// }
//
// byte[] bytes = api.RSAPriKeySign(77,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF,
// TACryptConst.DIGEST_ALG_SHA256, 10, "1234567890".getBytes());
// System.out.println("簽名結果:" + Forms.byteToHexString(bytes));
// boolean b = api.RSAPubVerify(publicR77,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF,
// TACryptConst.DIGEST_ALG_SHA256, 10, bytes, "1234567890".getBytes());
// System.out.println("驗簽結果:" + b);
}
/**
* RSA加解密運算
*/
@Test
public void RSAencdata() throws TAException {
byte[] bytes = api.RSAPubEncData(11, 1, TACryptConst.DIGEST_ALG_SHA256, new byte[0], Forms.hexStringToByte("{createTime=1606380202000, createUserId=144, ip=124.204.XX.XX, key=SYJHD202011266020179058, orderNumber=SYJHD202011266020179058, productId=161391, scene=SYJHD}"));
System.out.println("公開金鑰加密結果:" + Forms.byteToHexString(bytes));
byte[] bytes1 = api.RSAPriDecData(11, 1, TACryptConst.DIGEST_ALG_SHA256,new byte[0], bytes);
System.out.println("私密金鑰解密結果:" + Forms.byteToHexString(bytes1));
}
/**
* RSA私密金鑰解密,私密金鑰受保護密鑰保護
*/
@Test
public void priDecryptRSA() throws TAException {
byte[] bytes = api.proRSAPriKeyDec (sm4Key, TACryptConst.KEY_ALG_SM4 , sm4CV, srcRSACipher, b, srcRSACipherMAC, TACryptConst.DIGEST_ALG_SHA256,
b, new byte[2], srcRSACipherTag, 2, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256,new byte[0], Forms.hexStringToByteArray("BFA03DB9BD0A4DE4809B59B04BF663E8E541B0CF********5FD9E0A80116771AC436ED1EDE46CF272FD1DD4D3A5174D2D178D9A21F3D"));
System.out.println("解密後的明文資料:" + Forms.byteToHexString(bytes));
}
/**
* RSA私密金鑰簽名,私密金鑰受保護密鑰保護
*/
@Test
public void privateSignRSA() throws TAException, IOException {
byte[] bytes = api.proRSAPriKeyDecSign(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, srcRSACipher, b, srcRSACipherMAC, TACryptConst.DIGEST_ALG_SHA256,
b, new byte[2], srcRSACipherTag, TACryptConst.DIGEST_ALG_SHA256, "1234567890".getBytes(), TACryptConst.PADDING_MODE_PSS, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256, 10);
System.out.println("簽名結果:" + Forms.byteToHexString(bytes));
boolean b = api.RSAPubVerify(srcRSApublicKey,TACryptConst.PADDING_MODE_PSS, TACryptConst.DIGEST_ALG_SHA256, TACryptConst.MGF, TACryptConst.DIGEST_ALG_SHA256, 10, bytes, "1234567890".getBytes());
System.out.println("驗簽結果:" + b);
}
/**
* RSA非對稱金鑰轉加密,由保護密鑰1轉為保護密鑰2加密
*/
@Test
public void RSAConversionEncryption() throws TAException {
ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, TACryptConst.KEY_TYPE_RSA,
-1, srcRSACipher, b, srcRSACipherMAC, TACryptConst.ENC_MODE_GCM, b, new byte[2], srcRSACipherTag,
0,
TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_ECB, b, new byte[2]);
for (int i = 0; i < bytes.size(); i++) {
System.out.println("第" + i + "個===" + Forms.byteToHexString(bytes.get(i)));
}
}
/**
* RSA非對稱金鑰保護匯入對稱金鑰
*/
@Test
public void tets1() throws TAException {
ArrayList<byte[]> bytes = api.RSAProImplSymm(srcRSAprivateKey, 2, TACryptConst.DIGEST_ALG_SHA256, new byte[10], 200,
TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("5C59EBCD0A48E51038853E490C76AD83122964E3********AD4FCF0A1D20DC5A0AAB878DADC04903CCE5B3D06219FDB4497905FBEA9E"), "916-zjl".getBytes());
System.out.println("LMK加密的對稱金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("對稱金鑰的校正值:" + Forms.byteToHexString(bytes.get(1)));
}
/* ***************************************************************************************************** */
/**
* 產生SM2/ECC金鑰組,保護祕密金鑰加密輸出
*/
@Test
public void generateProtectionKeySM2() throws TAException {
ArrayList<byte[]> bytes = api.proGenSM2OrECCKey (sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, 0x0007,
b, TACryptConst.ENC_MODE_GCM, b, new byte[16]);
System.out.println("DER編碼的公開金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("LMK加密的私密金鑰:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("保護祕密金鑰加密私密金鑰的密文:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("非對稱私密金鑰MAC:" + Forms.byteToHexString(bytes.get(3)));
System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));
}
/**
* 產生SM2演算法金鑰組,私密金鑰由LMK加密輸出
*/
@Test
public void generateSM2Key() throws TAException {
ArrayList<byte[]> bytes = api.genSM2Key();
System.out.println("DER編碼的公開金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("LMK加密的私密金鑰:" + Forms.byteToHexString(bytes.get(1)));
}
/**
* 產生ECC演算法金鑰組,私密金鑰由LMK加密輸出
*/
@Test
public void generateECCKey() throws TAException {
ArrayList<byte[]> bytes = api.genECCKey(0x0007);
System.out.println("DER編碼的公開金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("LMK加密的私密金鑰:" + Forms.byteToHexString(bytes.get(1)));
}
byte[] data = Forms.hexStringToByte("20D90A83A4654FB8****0371B374F76DEFA5");
/**
* ECC 簽名驗簽
*/
@Test
public void ECCPrivateKeySign() throws TAException {
byte[] bytes = api.priKeySign(0x0007, Forms.hexStringToByteArray("61971383CD4D760CF77C****4C1C935F18B4CCCFBF3A"), data);
System.out.println("ECC簽名結果:" + Forms.byteToHexString(bytes));
boolean b = api.pubKeyVerify(0x0007, Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********1ACA51CB99CD452FA11B5B6BBB4AA31C2DBCC696FC57C8F9F8F01948FE"), data, bytes);
System.out.println("ECC驗簽結果:" + b);
}
/**
* SM2 簽名 驗簽
*/
@Test
public void TestSm2() throws TAException {
byte[] bytes = api.priKeySign(0x0007, privateKeySM2, sm3);
System.out.println("簽名結果:" + Forms.byteToHexString(bytes));
boolean b = api.pubKeyVerify(0x0007, privateKeySM2DER, sm3, bytes);
System.out.println("驗簽結果:" + b);
}
@Test
public void SM2Sign() throws TAException {
byte[] baInData = "2222222222222222".getBytes();
//7.計算SM3摘要
System.out.println("資料摘要:SM3");
String sAlg = "SM3";
byte[] baUserId = new byte[0];
byte[] baPubKey = Forms.hexStringToByteArray("3059301306072A8648CE3D020106082A811CCF55********9A1AD40BEEE37267F8F1F97E67BCE29A4E1CCAB0979A1E85F81010E042");
byte[] baHashInitRes = api.HashInit(sAlg, baUserId, baPubKey);
byte[] baHashUpdateRes = api.HashUpdate(baHashInitRes, baInData);
byte[] baHashSm3 = api.HashFinalize(baHashUpdateRes);
System.out.println(String.format("資料摘要: %s", Forms.byteToHexString(baHashSm3)));
//8.非對稱金鑰簽名驗簽
System.out.println("資料非對稱簽名驗簽:SM2");
int iCurveId = 0x0007;
System.out.println(String.format("資料原文(雜湊值): %s", Forms.byteToHexString(baHashSm3)));
byte[] baSignatureSm2 = api.priKeySign(iCurveId, 2, baHashSm3);
System.out.println(String.format("資料簽名: %s", Forms.byteToHexString(baSignatureSm2)));
boolean blVerifyResSm2 = api.pubKeyVerify(iCurveId, baPubKey, baHashSm3, baSignatureSm2);
System.out.println(blVerifyResSm2);
}
byte[] sm2 = Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********55A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");
byte[] sm2PrivateKey = Forms.hexStringToByte("4F23C664B68C8A38B31F****66976CEA234A749F031D");
/**
* SM2加密解密運算
*/
@Test
public void TestSM2EncAndDec() throws TAException {
byte[] bytes = api.SM2PubKeyEnc(888, Forms.hexStringToByte("1111111111****111111111111111"));
System.out.println("加密結果:" + Forms.byteToHexString(bytes));
byte[] bytes1 = api.SM2PriKeyDec(888, bytes);
System.out.println("解密結果:" + Forms.byteToHexString(bytes1));
}
byte[] sm2Key = Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********55A4C790CDE94A1B179CC12A39A856755F6677E87905BD903987425AF3");
byte[] sm2Cipher = Forms.hexStringToByte("83E260209C09CC3F0103****FD8880E68AC28BFFF0F3");
byte[] sm2CipherMAC = Forms.hexStringToByte("8184BE3669****B673814E59E7700");
byte[] sm2CipherTag = Forms.hexStringToByte("8FD638CA4D****213F5777253D192");
byte[] sm2PriKey = Forms.hexStringToByte("4F23C664B68C8A38B31F****66976CEA234A749F031D");
/**
* ECC/SM2私密金鑰解密,私密金鑰受保護密鑰保護
*/
@Test
public void protectionPrivateKeyDecrypt() throws TAException {
byte[] bytes = api.proPriKeyDec(sm4Key, TACryptConst.KEY_ALG_SM4, sm4CV, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM,
b, new byte[2], sm2CipherTag, Forms.hexStringToByteArray("E9C17D82604F992BB3AB8FE0F766441DACC05EB7********32FACEC8316B880499E6E70260333E9F29CEBCF3F8E10C151F79445276F6"));
System.out.println("解密後的資料明文:" + Forms.byteToHexString(bytes));
}
/**
* ECC/SM2私密金鑰簽名,私密金鑰受保護密鑰保護
*/
@Test
public void privateSignSM2() throws TAException {
byte[] bytes = api.proPriKeySign(sm4Key,TACryptConst.KEY_ALG_SM4 , sm4CV, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM,
b, new byte[2], sm2CipherTag, Forms.hexStringToByteArray("20D90A83A4654FB8****0371B374F76DEFA5"));
System.out.println("ECC/SM2私密金鑰簽名結果(私密金鑰受保護密鑰保護):" + Forms.byteToHexString(bytes));
boolean b = api.pubKeyVerify(7, sm2Key, Forms.hexStringToByteArray("20D90A83A4654FB8****0371B374F76DEFA5"), bytes);
System.out.println("ECC/SM2公開金鑰驗簽結果(私密金鑰受保護密鑰保護)" + b);
}
/**
* SM2非對稱金鑰保護匯入對稱金鑰
*/
@Test
public void SM2ImplKEK() throws TAException {
ArrayList<byte[]> bytes = api.SM2ImplKEK(sm2PriKey, 300, TACryptConst.KEY_ALG_SM4, Forms.hexStringToByteArray("9A9161F87BCBD3E9BC8866B8706E8F75B682DA27********13440F2DAD9AE786E3D73349D78FA7915B3CB633EFD9A88E638D93297934"), "914-zjl".getBytes());
System.out.println("LMK加密的對稱金鑰:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("對稱金鑰的校正值:" + Forms.byteToHexString(bytes.get(1)));
}
/**
* SM2/ECC非對稱轉加密
*/
@Test
public void conversionEncryption() throws TAException {
ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, 2,
-1, sm2Cipher, b, sm2CipherMAC, TACryptConst.ENC_MODE_GCM, b, new byte[2], sm2CipherTag, 0,
TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_GCM, b, new byte[2]);
for (int i = 0; i < bytes.size(); i++) {
System.out.println("第" + i + "個===" + Forms.byteToHexString(bytes.get(i)));
}
}
/**
* 摘要運算,填充摘要資料
*/
@Test
public void testGenHash() throws TAException {
byte[] hash = genHash();
System.out.println("摘要結果:" + Forms.byteToHexString(hash));
// 計算校正正確摘要結果
String string = "704423DF78242B08E821F7F8FA05A5325AA1BD842BE4EB9827C765DFFF434C1A";
byte[] bytes3 = genHash();
System.out.println("驗證結果:" + Arrays.equals(Forms.hexStringToByteArray(string),bytes3));
String wrongHash = "669523DF78242B08E821F7F8FA05A5325AA1KD842BE4EB9827C765DFFF434C1A";
System.out.println("錯誤驗證結果:" + Arrays.equals(Forms.hexStringToByteArray(wrongHash),bytes3));
}
public byte[] genHash() throws TAException {
byte[] bytes2 = api.HashInit("SM3", new byte[0], privateKeySM2DER);
byte[] bytes = api.HashUpdate(bytes2, Forms.hexStringToByteArray("1234567890"));
byte[] bytes1 = api.HashFinalize(bytes);
return bytes1;
}
/**
* 產生隨機數
*/
@Test
public void genRandom() throws TAException {
String s = api.genRandom(15);
System.out.println(s);
}
/**
* 擷取加密機狀態
*/
@Test
public void getHSMstatus() throws TAException {
String hsMstatus = api.getHSMstatus();
System.out.println(hsMstatus);
}
/**
* lmk to kek
* @throws TAException
*/
@Test
public void test3() throws TAException {
ArrayList<byte[]> bytes = api.LMKToKEK(TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM, b,
new byte[2], 0, sm4Key,
new byte[0], new byte[0], 5, 0,
1, 0, TACryptConst.KEY_ALG_SM4,
sm4Key2, new byte[16]);
System.out.println("使用保護祕密金鑰加密密鑰密文:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("當選擇產生MAC時,輸出MAC:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("tags:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("密鑰校正值:" + Forms.byteToHexString(bytes.get(3)));
}
/**
* 其他祕密金鑰加密轉LMK加密
* @throws TAException
*/
@Test
public void otherEncKeyToLMLEncKey() throws TAException {
ArrayList<byte[]> bytes = api.otherEncKeyToLMLEncKey(0, 7, 6,
Forms.hexStringToByteArray("00000000000000000000000000000000"),
Forms.hexStringToByteArray("00000000000000000000000000000000"),
Forms.hexStringToByteArray("71802E75BD****996A9B9DA6616E9"),
0, Forms.hexStringToByteArray("B36847D6E8****4EEB65558A2626C"),
new byte[0], new byte[0], 5, -1,-1, new byte[0], 0, 7,
Forms.hexStringToByte("9940568000****9C7F45977D291AA"));
System.out.println("=============保護密鑰為對稱金鑰============");
for (int i = 0; i < bytes.size(); i++) {
System.out.println(Forms.byteToHexString(bytes.get(i)));
}
ArrayList<byte[]> bytes2 = api.otherEncKeyToLMLEncKey(2, -1, -1,
new byte[0], new byte[0], new byte[0],
888, new byte[0], new byte[0],
new byte[0], 1,
1, 1, new byte[0], 0, 7,
Forms.hexStringToByte("7C78EAFE26890D48096AB8141B1D5890BF1921DD********5329ADED546F44C52C8F49EAC46647650D9B983224E9E005CFCAA88B019D"));
System.out.println("=============保護密鑰為ECC密鑰============");
for (int i = 0; i < bytes2.size(); i++) {
System.out.println(Forms.byteToHexString(bytes2.get(i)));
}
ArrayList<byte[]> bytes1 = api.otherEncKeyToLMLEncKey(1, -1, -1,
new byte[0], new byte[0], new byte[0],
11, new byte[0], new byte[0], new byte[0], 3,
1, 1, new byte[0], 0, 7,
Forms.hexStringToByte("6149EE02F14EE6420BC2B462003CCCE2413CE491********E2CE400522E06DCBAB44213A85B668764EC33EE71D372F5A904252A539AA"));
System.out.println("=============保護密鑰為RSA密鑰============");
for (int i = 0; i < bytes1.size(); i++) {
System.out.println(Forms.byteToHexString(bytes1.get(i)));
}
}
@Test
public void enveopEncAndDec() throws TAException {
byte[] bytes = api.enveopEnc(sm2Key, "1111111111111111".getBytes());
System.out.println("數位信封封裝結果:" + Forms.byteToHexString(bytes));
byte[] bytes1 = api.enveopDec(sm2PriKey, bytes);
System.out.println("數位信封拆封結果:" + new String(bytes1));
}
/**
* 對稱金鑰轉加密 & 非對稱轉加密
*/
@Test
public void symmetryConversionEncryptionAES256() throws TAException {
ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_AES256,
Forms.hexStringToByteArray("5BD90CDDBC8645B4****96B6E52CC003D04F"),
Forms.hexStringToByteArray("F8B6****4FD3"),
TACryptConst.KEY_TYPE_SYMMETRY,
TACryptConst.KEY_ALG_AES256,
Forms.hexStringToByteArray("CFE8E3D44F753D3F****88EF70B54E65E232"), b,
Forms.hexStringToByteArray("8F2440B220****7D8D807A832A19F"), TACryptConst.ENC_MODE_GCM, b, new byte[22],
Forms.hexStringToByteArray("B5294D5910****80774B61BA48FA4"),
0,
TACryptConst.KEY_ALG_SM4, sm4Key2, sm4Key2CV, b, TACryptConst.ENC_MODE_CBC, b, new byte[12]);
for (int i = 0; i < bytes.size(); i++) {
System.out.println("第" + i + "個===" + Forms.byteToHexString(bytes.get(i)));
}
}
/**
* 對稱金鑰轉加密 & 非對稱轉加密
*/
@Test
public void symmetryConversionEncryption() throws TAException {
ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4,
Forms.hexStringToByteArray("CBDCCE3378****E0B3BAA46CF3557"),
Forms.hexStringToByteArray("F668****C2AD"),
0,TACryptConst.KEY_ALG_SM4,
Forms.hexStringToByteArray("6BFC84C39C****6C7FA2A30C912A1"), b,
Forms.hexStringToByteArray("AB75C62580****39327B45881F589"), TACryptConst.ENC_MODE_GCM,
b, new byte[0], Forms.hexStringToByteArray("4A501743FA****4A0A8705192C1C8"),0,
TACryptConst.KEY_ALG_SM4,
Forms.hexStringToByteArray("CBDCCE3378****E0B3BAA46CF3557"),
Forms.hexStringToByteArray("F668****C2AD"), b, TACryptConst.ENC_MODE_GCM, b, new byte[0]);
for (int i = 0; i < bytes.size(); i++) {
System.out.println("第" + i + "個===" + Forms.byteToHexString(bytes.get(i)));
}
}
/**
* 對稱金鑰轉加密 & 非對稱轉加密
*/
@Test
public void symmetryConversionEncryption1() throws TAException {
ArrayList<byte[]> bytes = api.conversionEncryption(0, TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV,
TACryptConst.KEY_TYPE_ECC_OR_SM2,
TACryptConst.KEY_ALG_SM4,
Forms.hexStringToByteArray("83E260209C09CC3FEFDE****27A17AEB2C8919E1E4CF"), b,
Forms.hexStringToByteArray("E60EFC4882****F68D0EB622298FB"),
TACryptConst.ENC_MODE_GCM, b, new byte[16],
Forms.hexStringToByteArray("B200ED220D****C4438649057EB02"),
0,
TACryptConst.KEY_ALG_SM4, sm4Key, sm4CV, b, TACryptConst.ENC_MODE_GCM, b, new byte[16]);
for (int i = 0; i < bytes.size(); i++) {
System.out.println("第" + i + "個===" + Forms.byteToHexString(bytes.get(i)));
}
}
/**
* 對稱演算法 CMK 保護匯入非對稱CMK
*/
@Test
public void importCMKByCMK() throws TAException {
ArrayList<byte[]> bytes = api.importCMKByCMK("zjlimpl".getBytes(), 7,
6, //保護CMK DomainKey 加密 CMK 使用演算法模式標識
new byte[16], //ECB 模式解密時使用的 IV 資料
new byte[16], //GCM 模式解密時的認證資料
Forms.hexStringToByteArray("566F7CE9E5****F02D7A7667E3F7C"), //GCM 模式解密時的 MAC 值
Forms.hexStringToByteArray("DA23B170CE****772B3F2AE2CCA97"),//密鑰密文
Forms.hexStringToByteArray("7192C7C6F1****FE8A51BA9256C87"), //GCM tags
6, //保護祕密金鑰加密模式
new byte[16],//保護密鑰IV
new byte[16], //認證資料AAD
Forms.hexStringToByteArray("8DE9DFEE4B****1C08A38BDD8A92F"), //tags
5,//保護祕密金鑰加密填充方式
12, //工作階段金鑰類型
7, //會話CMK 非對稱金鑰的演算法標識
Forms.hexStringToByteArray("420B9FE23A2B162F3C4574919E9EBD44040F7C53********0B18990EF5C6F3A93AB80B41458311EA9F9A1890752427E24F5062AD4A"),//會話私密金鑰密文資料
"32-1".getBytes(),//會話DomainKey 標籤
6,//會話DomainKey 加密 CMK 使用演算法模式標識
new byte[16],//會話加密上下文(非 ECB 模式加密時使用的 IV 資料)
new byte[16]//會話認證上下文資料(GCM 模式加密時的認證資料)
);
System.out.println("使用保護祕密金鑰加密密鑰密文:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("MAC:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("tags:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("密鑰校正值:" + Forms.byteToHexString(bytes.get(3)));
}
@Test
public void testData() throws TAException {
//產生對稱金鑰,保護密鑰保護輸出
ArrayList<byte[]> bytes = api.proGenSymmKey(603,
-1, null, TACryptConst.KEY_ALG_SM4, b,
TACryptConst.ENC_MODE_GCM,b, b);
System.out.println("LMK加密的工作階段金鑰密文:" + Forms.byteToHexString(bytes.get(0)));
System.out.println("工作階段金鑰的校正值:" + Forms.byteToHexString(bytes.get(1)));
System.out.println("保護祕密金鑰加密的工作階段金鑰密文:" + Forms.byteToHexString(bytes.get(2)));
System.out.println("工作階段金鑰的MAC值:" + Forms.byteToHexString(bytes.get(3)));
System.out.println("tags:" + Forms.byteToHexString(bytes.get(4)));
System.out.println("-------------------------------------------------");
//對稱金鑰(受保護密鑰保護)加密資料
ArrayList<byte[]> bytes1 = api.proKeyEncData(603, -1, null,
bytes.get(2),
b, bytes.get(3), TACryptConst.ENC_MODE_GCM,
b, b, bytes.get(4),
TACryptConst.KEY_ALG_SM4, 0, 0,
new byte[16], TACryptConst.KEY_ALG_SM4, TACryptConst.ENC_MODE_GCM,
Forms.hexStringToByteArray("0000000000000000000000000000000000000000********353F49C7164DAE6C691FC25CD494D9A28D0F6C4B51F3BB9DC85ADDBE09"), new byte[16], new byte[16]);
System.out.println("密文: " + Forms.byteToHexString(bytes1.get(0)));
System.out.println("tag: " + Forms.byteToHexString(bytes1.get(1)));
}
@Test
public void agreementKey() throws TAException {
// byte[] bytes = api.agreementKey(0x02CB, 4, 4, Forms.hexStringToByte("3076301006072A8648CE3D020106052B81040022********5645477442F9BF8BE9BF81EAD69CDA6C63FCF5244A383C57DDB62465E63B"));
// System.out.println("secp384r1協商結果:" + Forms.byteToHexString(bytes));
// byte[] bytes1 = api.agreementKey(0x0007, 3, 6, Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********DF9A3DF50D67073CF246FC3406337B50E987F2AC3943D2FF5C7ECAD197"));
// System.out.println("0x0007協商結果:" + Forms.byteToHexString(bytes1));
// byte[] bytes2 = api.agreementKey(0x0007, 3, Forms.hexStringToByte("E59842CEEC68775E****F7DF23E08F7F6B8D"), Forms.hexStringToByte("3059301306072A8648CE3D020106082A811CCF55********B972EB19EA77A6AB74F345688B8458F1015885FCE435A4E3679DE0E34F"));
// System.out.println("0x0007外部私密金鑰明文協商結果:" + Forms.byteToHexString(bytes2));
// byte[] bytes3 = api.agreementKey(0x039B, 0, 5, Forms.hexStringToByte("304A301406072A8648CE3D020106092B24030302********868F7D34BABEEB5A20F7DF5543091DD740DD3780B5EBEF631615571ADC"));
// System.out.println("0x039B協商結果:" + Forms.byteToHexString(bytes3));
byte[] bytesA = api.agreementKey(0x019F, 3, 13, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D********7558F1DA9AC8CDF5E7FA72C9931FA90EE06B3CE07E13A7845A05BA7C73"));
System.out.println(bytesA.length);
System.out.println("0x0007協商結果:" + Forms.byteToHexString(bytesA));
byte[] bytesB = api.agreementKey(0x019F, 3, 15, Forms.hexStringToByte("3059301306072A8648CE3D020106082A8648CE3D********C7AB0964E53872FBF0511FF6E7661CF94B7D82C8BF78D211B1FA73F271"));
System.out.println("0x0007協商結果:" + Forms.byteToHexString(bytesB));
}
/**
* 根據金鑰索引擷取對稱金鑰詳情
*/
@Test
public void getKeyInfo() throws TAException {
String[] keyInfo = api.getKeyInfo(66);
System.out.println(keyInfo[0]);
}
/**
* 根據金鑰索引擷取RSA公開金鑰
*/
@Test
public void exportRSAPublicKey() throws TAException, IOException {
ArrayList<byte[]> keyInfo = api.exportRSAPublicKey(77,0);
System.out.println(Forms.byteToHexString(keyInfo.get(0)));
}
/**
* 根據金鑰索引擷取ECC公開金鑰
*/
@Test
public void ExportEncPublicKey() throws TAException {
byte[] keyInfo = api.exportECCPublicKey(66,0);
System.out.println(Forms.byteToHexString(keyInfo));
}
@Test
public void generateAndSaveKey() throws Exception {
ArrayList<byte[]> symmKey = api.generateSymmKey(7, 32);
for (int i = 0; i < symmKey.size(); i++) {
System.out.println(Forms.byteToHexString(symmKey.get(i)));
}
boolean b = api.generateRSAKey(2048, 65537, 13);
System.out.println("產生並儲存RSA金鑰組" + (b ? "成功":"失敗"));
boolean b1 = api.generateECCKey(0x019F, 8);
System.out.println("產生並儲存ECC金鑰組" + (b1 ? "成功":"失敗"));
}
}