說明
Java 語言 sdk,底層通過 C 實現算法,通過 jni 封裝後,作為本地接口供 Java 語言調用。
錯誤碼
異常碼 |
說明 |
0 |
正常返回 |
10010 |
sdk 初始化錯誤 |
10011 |
DataKeyManager 無效,不能為 null |
10013 |
加密上下文超過最大長度,最大長度為1024 |
10012 |
算法不支持 |
10014 |
解密密鑰獲取失敗 |
10015 |
加密密鑰過期,重置密鑰 |
10016 |
參數不能為空 |
10017 |
無效的 key |
10018 |
無效的 iv |
10019 |
aad 不能為 null |
10020 |
密鑰緩存初始化錯誤 |
20011 |
數據密鑰創建異常 |
20012 |
簽名檢查異常 |
20013 |
騰訊 KMS 加密或解密異常 |
20014 |
無效參數,主密鑰個數超過最大值,最大值為5 |
20015 |
域名為 null,且環境變量未設置域名 |
20016 |
主密鑰 keyId 或 region 為空 |
初始化 SDK 接口
EncryptSdk.initSdk
- 功能描述:檢驗用戶是否開通 KMS 旗艦版服務。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
region |
是 |
String |
CMK 地域信息字符串,詳見產品支持的 地域列表 |
secretId |
是 |
String |
雲帳戶 API 密鑰 ID 值 |
secretKey |
是 |
String |
雲帳號 API 密鑰 Key 值 |
domainName |
是 |
String |
域名信息字符串 |
- 返回值:接口返回一個整數。當接口返回值為0,表示初始化成功。當接口返回值非0,代表初始化失敗。
注意:
需注意 SecretId 和 SecretKey 的保密存儲: 騰訊雲接口認證主要依靠 SecretID 和 SecretKey,SecretID 和 SecretKey 是用戶的唯一認證憑證。業務系統需要該憑證調用騰訊雲接口。需注意 SecretID 和 SecretKey 的權限控制:建議使用子帳號,根據業務需要進行接口授權的方式管控風險。需注意 domainName 的設置:如果 domainName 入參為"",則從環境變量 TENCENT_SDK_DOMAIN 中讀取值,反之,則以入參為準。
KMS加密方式的接口說明
EncryptSdk.createKeyManager
- 功能描述:初始化用戶的主密鑰,包含主密鑰信息、密鑰加密次數、密鑰生效時間等,具體看後續參數。
- 參數說明:
參數名稱 |
必選 |
類型 |
描述 |
masterKey |
是 |
List |
主密鑰(CMK)信息列表 |
msgCount |
是 |
KeyCache |
每個緩存 DataKey 可加密的消息數量,加密的數量達到後,會重新向 KMS 後台請求,生成新的 DataKey,設置為0表示沒有限制使用次數。 |
enExpiretime |
是 |
KeyCache |
加密使用的 DataKey 在緩存中的有效期,單位為秒。和消息數量一起生效,消息數量超過或者超時時間達到,都會觸發 DataKey 的替換,0表示不過期。 |
deExpiretime |
是 |
KeyCache |
解密使用的 DataKey 緩存的有效期,單位為秒,0表示不過期。 |
secretId |
是 |
String |
雲帳戶 API 密鑰 ID 值 |
secretKey |
是 |
String |
雲帳號 API 密鑰 Key 值 |
- 返回值:接口返回 DataKeyManager 對象。當接口返回值正常,表示初始化成功。當接口返回值拋異常,代表初始化失敗。
注意:
初始化 keyManager 對象方法:
EncryptSdk.createKeyManager(List masterKey, KeyCache keyCache,String secretId, String secretKey)。masterKey:主密鑰的集合,最多5個主密鑰。keyChe:密鑰緩存對象,三個成員變量 msgCount、enExpiretime、deExpiretime。
EncryptSdk.Encrypt
- 功能描述:使用 KMS 平台創建的 DataKey,進行本地數據加密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
masterKeys |
是 |
List |
主密鑰(CMK)信息列表 |
source |
是 |
byte[] |
待加密的明文數據 |
keyManager |
是 |
kms_enc_sdk.KeyManager |
已經初始化的 KeyManager 結構體指針 |
algorithm |
是 |
KmsSdk.Algorithm |
算法枚舉值,參照後面算法列表 |
encryptionContext |
是 |
String |
用於標識 DataKey 的輔助欄位,key/value 對的 json 字符串格式,最大支持2048位元組。如:{"name":"test","date":"20200228"} |
blockSize |
是 |
int |
0 表示加密時不分塊加密,非0表示分塊加密以及分塊大小,單位 byte |
- 返回值:接口返回 EncryptResult 對象。當接口返回值正常,代表加密成功。當接口返回值拋異常,代表加密失敗。
注意:
加密後的數據,會加入 DataKey 相關信息,只能使用 KMS 密鑰保護方式的接口進行解密。
EncryptSdk.Decrypt
- 功能描述:方法用於解密密文,得到明文數據。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
加密後的數據 |
keyManager |
是 |
DataKeyManager |
已經初始化的 KeyManager 對象 |
- 返回值:接口返回 DecryptResult 對象。當接口返回值正常,代表解密成功。當接口返回值拋異常,代表解密失敗。
Algorithm 支持的加密算法列表
枚舉值 |
數值 |
說明 |
SM4_CBC_128_WITH_SIGNATURE |
1 |
使用 SM3HA C簽名的 SM4 CBC 模式 |
SM4_CBC_128 |
2 |
不使用簽名的 SM4 CBC 模式加密 |
SM4_GCM_128_WITH_SIGNATURE |
3 |
使用 SM3HAC 簽名的 SM4 GCM 模式 |
SM4_GCM_128 |
4 |
不使用簽名的 SM4 GCM 模式加密算法 |
SM4_CTR_128_WITH_SIGNATURE |
5 |
使用 SM3HAC 簽名的 SM4 CTR 模式 |
SM4_CTR_128 |
6 |
不使用簽名的 SM4 CTR 模式 |
SM4_ECB_128_WITH_SIGNATURE |
7 |
使用 SM3HAC 簽名的 SM4 ECB 模式 |
SM4_ECB_128 |
8 |
不使用簽名的 SM4 ECB 模式 |
原生加密方式接口說明
- 原生加密方式對應的服務也需要升級為旗艦版,與 KMS 密鑰保護方式相比,原生加密方式需要用戶自己生成加密密鑰進行加解密,來保證密鑰的安全性。出於安全與合規的考慮,建議用戶使用 KMS 密鑰保護方式。
- 其中CTR模式加密沒有填充,其他的模式加密採用 PKCS#7 標準進行填充。
EncryptSdk.genSm2KeyPair
- 功能描述:使用 SM2 算法生成密鑰對。
- 輸入參數:無需填充輸入參數。
- 返回值:接口返回一個字節數組(包含生成的公鑰值、私鑰值)。當接口返回返回值正常,表示獲取密鑰對成功。當接口返回值拋異常,代表獲取失敗。
EncryptSdk.sm2Sign
- 功能描述:使用 SM2 算法進行簽名。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pubKey |
是 |
byte[] |
公鑰內容,數據長度固定為64位元組 |
priKey |
是 |
byte[] |
私鑰內容,數據長度固定為32位元組 |
source |
是 |
byte[] |
原文數據 |
- 返回值:接口返回一個包含簽名內容的字節數組。當接口返回值正常,代表簽名成功。當接口返回值拋異常,代表簽名失敗。
注意:
公鑰和私鑰的長度為固定長度,用戶如果輸入長度不一致的數據,可能導致內存訪問異常。
EncryptSdk.sm2Verify
- 功能描述:使用 SM2 算法進行驗簽。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pubkey |
是 |
byte[] |
公鑰內容,數據長度固定為64位元組 |
sign |
是 |
byte[] |
簽名後的數據 |
source |
是 |
byte[] |
原文數據 |
- 返回值:接口返回一個 boolean 值。當接口返回值為 true,表示驗簽成功。當接口返回值非 true,代表驗簽失敗。
注意:
公鑰長度為固定長度64位元組,用戶如果輸入長度不一致的數據,可能導致內存訪問異常。
EncryptSdk.sm2Encrypt
- 功能描述:使用 SM2 算法進行加密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pubkey |
是 |
byte[] |
公鑰內容,數據長度為64位元組 |
source |
是 |
byte[] |
源數據 |
- 返回值:接口返回一個包含加密後的密文內容的字節數組。當接口返回值正常,代表加密成功。當接口返回值拋異常,代表加密失敗。
>! SM2 加密適用於小數據的場景,不建議加密超過256k的數據。
EncryptSdk.sm2Decrypt
- 功能描述:使用 SM2 算法進行解密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
prikey |
是 |
byte[] |
私鑰內容,數據長度固定為32位元組 |
source |
是 |
byte[] |
加密後的數據 |
- 返回值:接口返回一個包含解密後的明文內容的字節數組。當接口返回值正常,代表解密成功。當接口返回值拋異常,代表解密失敗。
EncryptSdk.sm2PemChangeToPubkey
- 功能描述:對 pem 格式的公鑰內容進行轉換。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pemPubKeyInfo |
是 |
byte[] |
pem 格式的公鑰信息 |
- 返回值:接口返回一個包含轉換後的公鑰內容的字節數組。當接口返回值正常,代表轉換成功。當接口返回值拋異常,代表轉換失敗。
EncryptSdk.hashForSM3WithSM2
- 功能描述:使用 Sm2GetKey 接口生成的公鑰,並基於 SM3 算法生成信息摘要。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
msg |
是 |
byte[] |
原文數據 |
pubKey |
是 |
byte[] |
公鑰內容,數據長度固定為64位元組 |
id |
是 |
byte[] |
ID 值 |
- 返回值:接口返回一個包含生成的摘要內容的字節數組。當接口返回值正常,代表摘要生成成功。當接口返回值拋異常,代表摘要生成失敗。
EncryptSdk.sm2SignWithDigest
- 功能描述:使用本地生成的消息摘要生成簽名
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pubKey |
是 |
byte[] |
公鑰內容,數據長度固定為64位元組 |
priKey |
是 |
byte[] |
私鑰內容,數據長度固定為32位元組 |
digest |
是 |
byte[] |
HashForSM3WithSM2 生成的摘要信息內容 |
- 返回值:接口返回一個包含生成的簽名內容的字節數組。當接口返回值正常,代表簽名成功。當接口返回值拋異常,代表摘要簽名失敗。
EncryptSdk.sm2VerifyWithDigest
- 功能描述:通過生成的摘要內容進行驗簽。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
pubKey |
是 |
byte[] |
公鑰內容,數據長度固定為64位元組 |
sig |
是 |
byte[] |
Sm2SignWithDigest 生成的簽名內容 |
digest |
是 |
byte[] |
HashForSM3WithSM2 生成的摘要信息內容 |
- 返回值:接口返回一個整數。當接口返回的整數信息為0,代表驗簽成功。當接口返回的整數信息為非0,代表摘要驗簽失敗。
EncryptSdk.sm3Hmac
- 功能描述:使用 SM3 哈希運算 Hmac 計算。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
原文數據 |
hmacKey |
是 |
byte[] |
計算 Hmac 的密鑰內容 |
- 返回值:接口返回一個包含 Hmac 內容的字節數組。當接口返回值正常,代表 Hmac 計算成功。當接口返回值拋異常,代表 Hmac 計算失敗。
EncryptSdk.sm3Digest
- 功能描述:使用 SM3 生成摘要。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
原文數據 |
- 返回值:接口返回一個包含摘要內容的字節數組。當接口返回值正常,代表生成摘要成功。當接口返回值拋異常,代表生成摘要失敗。
EncryptSdk.sm4CbcEncrypt/EncryptSdk.sm4CtrEncrypt
- 功能描述:方法是用於 SM4 加密算法 CBC、CTR 模式下的加密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
原文數據 |
Key |
是 |
byte[] |
用戶自定義的SM4密鑰,長度固定為128位(16位元組),不能設置為空 |
iv |
是 |
byte[] |
初始化向量,固定為128位(16位元組),不能設置為空 |
- 返回值:接口返回一個包含加密後的密文內容的字節數組。當接口返回值正常,代表加密成功。當接口返回值拋異常,代表加密失敗。
EncryptSdk.sm4CbcDecrypt/EncryptSdk.sm4CtrDecrypt
- 功能描述:方法是用於 SM4 加密算法 CBC、CTR 模式下的解密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
加密後的數據 |
Key |
是 |
byte[] |
用戶自定義的 SM4 密鑰,長度固定為128位(16位元組),不能設置為空 |
iv |
是 |
byte[] |
初始化向量,固定為128位(16位元組),不能設置為空 |
- 返回值:接口返回一個包含解密後的明文內容的字節數組。當接口返回值正常,代表解密成功。當接口返回值拋異常,代表解密失敗。
EncryptSdk.sm4EcbEncrypt
- 功能描述:方法是用於 SM4 加密算法 ECB 模式下的加密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
原文數據 |
Key |
是 |
byte[] |
用戶自定義的 SM4 密鑰,長度固定為128位(16位元組),不能設置為空 |
- 返回值:接口返回一個包含加密後的密文內容的字節數組。當接口返回值正常,代表加密成功。當接口返回值拋異常,代表加密失敗。
EncryptSdk.sm4EcbDecrypt
- 功能描述:方法是用於 SM4 加密算法 ECB 模式下的解密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
加密後的數據 |
Key |
是 |
byte[] |
用戶自定義的 SM4 密鑰,長度固定為128位(16位元組),不能設置為空 |
- 返回值:接口返回一個包含解密後的明文內容的字節數組。當接口返回值正常,代表解密成功。當接口返回值拋異常,代表解密失敗。
EncryptSdk.sm4GcmEncrypt
- 功能描述:方法是用於 SM4 加密算法 GCM 模式下的加密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
原文數據 |
key |
是 |
byte[] |
用戶自定義的 SM4 密鑰,長度固定為128位(16位元組),不能設置為空 |
iv |
是 |
byte[] |
初始化向量,不能設置為空 |
aad |
是 |
byte[] |
附加校驗信息 |
- 返回值:接口返回一個 Map 對象。當接口返回值正常,代表加密成功。當接口返回值拋異常,代表加密失敗。
EncryptSdk.sm4GcmDecrypt
- 功能描述:方法是用於 SM4 加密算法 GCM 模式下的解密。
- 輸入參數:
參數名稱 |
必選 |
類型 |
描述 |
source |
是 |
byte[] |
加密後的數據 |
key |
是 |
byte[] |
用戶自定義的 SM4 密鑰,長度固定為128位(16位元組),不能設置為空 |
iv |
是 |
byte[] |
初始化向量,不能設置為空 |
aad |
是 |
byte[] |
附加校驗信息 |
tag |
是 |
byte[] |
tag 值,即校驗碼 |
- 返回值:接口返回一個包含解密後的明文內容的字節數組。當接口返回值正常,代表解密成功。當接口返回值拋異常,代表解密失敗。
接口調用示例
說明:
接口示例適用以下加密方式:
KMS 方式加解密原生加密方式
import com.ciphergateway.sdk.EncryptSdk;
import com.ciphergateway.sdk.exception.SdkException;
import com.ciphergateway.sdk.exception.SdkExceptionEnum;
import com.ciphergateway.sdk.vo.*;
import kmsmsg.KmsSdk;
import javax.xml.bind.DatatypeConverter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @ClassName : TestSdk
* @Description : ${description}
* @Author : crisp
* @Date: 2020-06-28 14:25
*/
public class DemoSdkTest {
public static String secretId = "replace-with-real-secretId";
public static String secretKey = "replace-with-real-secretKey";
public static String keyID1_guangzhou="replace-with-realkeyid";
public static String keyID2_shanghai="replace-with-realkeyid";
public static String algorithmPath = "real-algorithm-path"; //libkms_enc_sdk_jni.so文件路徑,例如:/root/user/kms_enc_sdk_java/lib/linux/libkms_enc_sdk_jni.so
private static int ret = 0;
static {
//初始化sdk,此處啟動程序只需執行一次,返回0說明初始化成功
try {
ret = EncryptSdk.initSdk("ap-shanghai", secretId, secretKey, null);
} catch (SdkException e) {
e.printStackTrace();
}
System.out.println("init encrypt worker status is " + ret);
//linux 環境下加載方式
System.load(algorithmPath);
//windows環境下配置方式,需要把windows庫的路徑加入到系統的環境變量(path環境變量)中
//System.load("D:\\java\\tencent-kms-sdk\\src\\main\\resources\\lib\\windows\\libkms_enc_sdk_jni.dll");
}
public static void main(String[] args) throws UnsupportedEncodingException, SdkException {
if (ret != 0) {
throw new SdkException(new ErrorInfo(SdkExceptionEnum.TENCENT_DOMAIN_NAME_NULL.message, null).toString());
}
MasterKey key1 = new MasterKey();
key1.setKeyId(keyID1_guangzhou);
key1.setRegion("ap-guangzhou");
MasterKey key2 = new MasterKey();
key2.setKeyId(keyID2_shanghai);
key2.setRegion("ap-shanghai");
//構建datamanager所需要的參數
List<MasterKey> list = Arrays.asList(key1, key2, key1, key2, key1);
DataKeyManager dataKeyManager = null;
try {
dataKeyManager = EncryptSdk.createKeyManager(list, new KeyCache(2, 0, 0), secretId, secretKey);
} catch (Exception e) {
e.printStackTrace();
} finally {
//System.out.println(" error occur");
}
String cipherBlob = "test1234567890";
long start = System.currentTimeMillis();
String encryptionContext = "{\"ceshi\":\"fgdfgdfgdg\"}";
//Test_CBCEnAndDe_withEncryptionContextNotjosnformatParams();
for (int i = 0; i < 5; i++) {
// encryptionContext = Constant.EMPTY;
//encryptionContext = "afa";
EncryptResult result = null;
try {
result = EncryptSdk.Encrypt(list, cipherBlob.getBytes(), dataKeyManager, KmsSdk.Algorithm.SM4_GCM_128, encryptionContext, 7);
// System.out.println("------------result------------"+result);
} catch (Exception e) {
e.printStackTrace();
}
try {
DecryptResult decryptResult = EncryptSdk.Decrypt(result.getCipher(), dataKeyManager);
if (new String(decryptResult.getPlainText()).equals(cipherBlob)) {
continue;
} else {
System.out.println("decrypt faild");
}
} catch (Exception e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("encrypt 5 times costs: "+(end-start)/1000 +" seconds");
System.out.println("----------------------------------------------------------------------------------------------------------------------------------------------");
System.out.println("begin to en");
com.ciphergateway.encryptsdk.EncryptSdk enf = new com.ciphergateway.encryptsdk.EncryptSdk();
String data = "1234567890123456";
String key = "0123456789abcdef";
String iv = "0123456789abcdef";
String aad = "0123456789abcdef";
String region = "ap-guangzhou";
byte[] pubkey = {(byte) 0xcd, (byte) 0x70, (byte) 0x6a, (byte) 0xc4, (byte) 0xc6, (byte) 0x00, (byte) 0x7c, (byte) 0x67, (byte) 0xed, (byte) 0xa7, (byte) 0xdc, (byte) 0xa7, (byte) 0x3f, (byte) 0x8a, (byte) 0xed, (byte) 0x55, (byte) 0x2d, (byte) 0x75, (byte) 0x12, (byte) 0x21, (byte) 0xb5, (byte) 0x8a, (byte) 0x81, (byte) 0xaa, (byte) 0xbb, (byte) 0xd6, (byte) 0xe2, (byte) 0x85, (byte) 0x15, (byte) 0xa5, (byte) 0x23, (byte) 0xf3, (byte) 0x5e, (byte) 0xe5, (byte) 0x05, (byte) 0x9d, (byte) 0xf0, (byte) 0x4b, (byte) 0x1b, (byte) 0xee, (byte) 0x7e, (byte) 0x90, (byte) 0x21, (byte) 0x50, (byte) 0x58, (byte) 0x07, (byte) 0x3a, (byte) 0xd5, (byte) 0x63, (byte) 0x9f, (byte) 0x0a, (byte) 0xd0, (byte) 0x2e, (byte) 0x33, (byte) 0x67, (byte) 0xe5, (byte) 0xd9, (byte) 0x71, (byte) 0x66, (byte) 0xd9, (byte) 0x57, (byte) 0xeb, (byte) 0x1a, (byte) 0xb1};
byte[] prikey = {(byte) 0x55, (byte) 0x13, (byte) 0xa7, (byte) 0xe3, (byte) 0x18, (byte) 0x4f, (byte) 0x28, (byte) 0x55, (byte) 0xd3, (byte) 0x20, (byte) 0x9a, (byte) 0x2f, (byte) 0x5e, (byte) 0x24, (byte) 0xd3, (byte) 0x6c, (byte) 0xa9, (byte) 0xb2, (byte) 0x8e, (byte) 0x13, (byte) 0x3d, (byte) 0xa9, (byte) 0x74, (byte) 0xb8, (byte) 0xbc, (byte) 0xff, (byte) 0xfa, (byte) 0xa9, (byte) 0x7e, (byte) 0x8e, (byte) 0x0a, (byte) 0x5a};
//sm4 ctr enc
byte[] enctrdata = EncryptSdk.sm4CtrEncrypt(data.getBytes(), key.getBytes(), iv.getBytes());
////sm4 ctr dec
byte[] dectrdata = EncryptSdk.sm4CtrDecrypt(enctrdata, key.getBytes(), iv.getBytes());
System.out.println("Sm4CtrDecrypt:" + new String(dectrdata));
//sm4 cbc enc
byte[] encbcdata = EncryptSdk.sm4CbcEncrypt(data.getBytes(), key.getBytes(), iv.getBytes());
//sm4 cbc dec
byte[] decbcdata = EncryptSdk.sm4CbcDecrypt(encbcdata, key.getBytes(), iv.getBytes());
String result = new String(decbcdata);
System.out.println("Sm4CbcDecrypt:" + result);
//sm4 ecb enc
byte[] enecbdata = EncryptSdk.sm4EcbEncrypt(data.getBytes(), key.getBytes());
//sm4 ecb dec
byte[] deecbdata = EncryptSdk.sm4EcbDecrypt(enecbdata, key.getBytes());
System.out.println("Sm4EcbEncrypt:" + new String(deecbdata));
//sm4 gcm enc
Map<String, byte[]> map = EncryptSdk.sm4GcmEncrypt(data.getBytes(), key.getBytes(), iv.getBytes(), "".getBytes());
if (!map.isEmpty()) {
byte[] realdata = map.get("data");
byte[] tagdata = map.get("tag");
//sm4 gcm dec
byte[] degcmdata = EncryptSdk.sm4GcmDecrypt(realdata, key.getBytes(), iv.getBytes(), "".getBytes(), tagdata);
System.out.println("Sm4GcmDecrypt:" + new String(degcmdata));
}
//sm3計算hmac 值
byte[] hmac = EncryptSdk.sm3Hmac(data.getBytes(), key.getBytes());
System.out.print("Sm3Hmac(len):");
System.out.println(hmac.length);
//生成公私鑰對,字節數組長度是96字節,前64字節為公鑰,後32字節為私鑰
byte[] keyPair = EncryptSdk.genSm2KeyPair();
System.out.println("The derived key --> " + DatatypeConverter.printHexBinary(keyPair));
String plainmsg = "hello, bingo";
System.out.println("the input message " + plainmsg);
//sm2 加密
byte[] sm2encbyte = EncryptSdk.sm2Encrypt(Arrays.copyOf(keyPair, 64), plainmsg.getBytes());
System.out.println("sm2 encrypt --> " + DatatypeConverter.printHexBinary(sm2encbyte));
//sm2解密
byte[] sm2decbyte = EncryptSdk.sm2Decrypt(Arrays.copyOfRange(keyPair, keyPair.length - 32, keyPair.length), sm2encbyte);
System.out.println("sm2 decrypt --> " + new String(sm2decbyte));
//簽名
byte[] sign = EncryptSdk.sm2Sign(pubkey, prikey, data.getBytes());
//驗證簽名
boolean isRight = EncryptSdk.sm2Verify(pubkey, sign, data.getBytes());
System.out.println(isRight);
System.out.println("=============================2021-02-24========================================");
//sm3 digest
byte[] digest_message = EncryptSdk.sm3Digest(data.getBytes());
System.out.println("digest message " + DatatypeConverter.printHexBinary(digest_message));
String smid = "1234567812345678";
byte[] sm2sm3hash = EncryptSdk.hashForSM3WithSM2(data.getBytes(), pubkey, smid.getBytes());
System.out.println("HashForSM3WithSM2 hash " + DatatypeConverter.printHexBinary(sm2sm3hash));
byte[] sm2digest = EncryptSdk.sm2SignWithDigest(pubkey, prikey, sm2sm3hash);
System.out.println("Sm2SignWithDigest " + DatatypeConverter.printHexBinary(sm2digest));
int sm2verify1 = EncryptSdk.sm2VerifyWithDigest(pubkey, sm2digest, sm2sm3hash);
System.out.println("Sm2VerifyWithDigest " + sm2verify1);
String pem = "-----BEGIN PUBLIC KEY-----\n";
pem += "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5rwEIw9e5fX87uSN7C/vy6lyEZ2R\n";
pem += "gzLqWLnY8EPN1C+nJP2v4rLgaQCbHV38+vBVLimbLmdccLM69R83JxpxuQ==\n";
pem += "-----END PUBLIC KEY-----\n";
byte[] pk = EncryptSdk.sm2PemChangeToPubkey(pem.getBytes());
System.out.println("Sm2PemChangeToPubkey " + DatatypeConverter.printHexBinary(pk));
}
}
小夥伴們有興趣想了解內容和更多相關學習資料的請點讚收藏+評論轉發+關注我,後面會有很多乾貨。我有一些面試題、架構、設計類資料可以說是程式設計師面試必備!
所有資料都整理到網盤了,需要的話歡迎下載!私信我回復【111】即可免費獲取
出處:https://cloud.tencent.com/document/product/573/58186