• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用SM2非对称密钥加解密(C/C++)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10对应的算法规格请查看[非对称密钥加解密算法规格:SM2](crypto-asym-encrypt-decrypt-spec.md#sm2)。
11
12**加密**
13
141. 调用[OH_CryptoAsymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygenerator_create)、[OH_CryptoAsymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygenerator_generate),生成SM2密钥类型为SM2_256的非对称密钥对(keyPair)。keyPair对象中包括公钥PubKey、私钥PriKey。
15
16   如何生成SM2非对称密钥对,开发者可参考下文示例,并结合[非对称密钥生成和转换规格:SM2](crypto-asym-key-generation-conversion-spec.md#sm2)和[随机生成非对称密钥对](crypto-generate-asym-key-pair-randomly-ndk.md)理解。参考文档与当前示例可能存在入参差异,请在阅读时注意区分。
17
182. 调用[OH_CryptoAsymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_create),指定字符串参数'SM2_256|SM3',创建非对称密钥类型为SM2_256、摘要算法为SM3的Cipher实例,用于完成加解密操作。
19
203. 调用[OH_CryptoAsymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_init),设置模式为加密(CRYPTO_ENCRYPT_MODE),指定加密密钥(keyPair),初始化加密Cipher实例。
21
224. 调用[OH_CryptoAsymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_final),传入明文,获取加密后的数据。
23
24   OH_CryptoAsymCipher_Final输出结果可能为NULL,在访问具体数据前,需要先判断结果是否为NULL,避免产生异常。
25
26**解密**
27
281. 由于SM2算法的Cipher实例不支持重复init操作,需要调用[OH_CryptoAsymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_create),重新生成Cipher实例。
29
302. 调用[OH_CryptoAsymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_init),设置模式为解密(CRYPTO_DECRYPT_MODE),指定解密密钥(keyPair)初始化解密Cipher实例。
31
323. 调用[OH_CryptoAsymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_final),传入密文,获取解密后的数据。
33
34```C++
35#include "CryptoArchitectureKit/crypto_architecture_kit.h"
36#include <algorithm>
37#include <vector>
38#include <string>
39
40static std::vector<uint8_t> doTestSm2Enc(OH_CryptoKeyPair *keyPair, std::vector<uint8_t> &plainText)
41{
42    std::vector<uint8_t> cipherText;
43    OH_CryptoAsymCipher *cipher = nullptr;
44    OH_Crypto_ErrCode ret = OH_CryptoAsymCipher_Create("SM2_256|SM3", &cipher);
45    if (ret != CRYPTO_SUCCESS) {
46        return std::vector<uint8_t>{};
47    }
48
49    ret = OH_CryptoAsymCipher_Init(cipher, CRYPTO_ENCRYPT_MODE, keyPair);
50    if (ret != CRYPTO_SUCCESS) {
51        OH_CryptoAsymCipher_Destroy(cipher);
52        return std::vector<uint8_t>{};
53    }
54
55    Crypto_DataBlob in = {};
56    in.data = plainText.data();
57    in.len = plainText.size();
58    Crypto_DataBlob out = {};
59    ret = OH_CryptoAsymCipher_Final(cipher, &in, &out);
60    if (ret != CRYPTO_SUCCESS) {
61        OH_CryptoAsymCipher_Destroy(cipher);
62        return std::vector<uint8_t>{};
63    }
64    cipherText.insert(cipherText.end(), out.data, out.data + out.len);
65    OH_Crypto_FreeDataBlob(&out);
66
67    OH_CryptoAsymCipher_Destroy(cipher);
68    return cipherText;
69}
70
71static std::vector<uint8_t> doTestSm2Dec(OH_CryptoKeyPair *keyPair, std::vector<uint8_t> &encryptText)
72{
73    std::vector<uint8_t> decryptText;
74    OH_CryptoAsymCipher *cipher = nullptr;
75    OH_Crypto_ErrCode ret = OH_CryptoAsymCipher_Create("SM2_256|SM3", &cipher);
76    if (ret != CRYPTO_SUCCESS) {
77        return std::vector<uint8_t>{};
78    }
79
80    ret = OH_CryptoAsymCipher_Init(cipher, CRYPTO_DECRYPT_MODE, keyPair);
81    if (ret != CRYPTO_SUCCESS) {
82        OH_CryptoAsymCipher_Destroy(cipher);
83        return std::vector<uint8_t>{};
84    }
85
86    Crypto_DataBlob in = {};
87    in.data = encryptText.data();
88    in.len = encryptText.size();
89    Crypto_DataBlob out = {};
90    ret = OH_CryptoAsymCipher_Final(cipher, &in, &out);
91    if (ret != CRYPTO_SUCCESS) {
92        OH_CryptoAsymCipher_Destroy(cipher);
93        return std::vector<uint8_t>{};
94    }
95    decryptText.insert(decryptText.end(), out.data, out.data + out.len);
96    OH_Crypto_FreeDataBlob(&out);
97
98    OH_CryptoAsymCipher_Destroy(cipher);
99    return decryptText;
100}
101
102static OH_Crypto_ErrCode doTestSm2EncMessage()
103{
104    OH_CryptoAsymKeyGenerator *keyGen = nullptr;
105    OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create("SM2_256", &keyGen);
106    if (ret != CRYPTO_SUCCESS) {
107        return ret;
108    }
109    OH_CryptoKeyPair *keyPair = nullptr;
110    ret = OH_CryptoAsymKeyGenerator_Generate(keyGen, &keyPair);
111    if (ret != CRYPTO_SUCCESS) {
112        OH_CryptoAsymKeyGenerator_Destroy(keyGen);
113        return ret;
114    }
115
116    std::string message = "This is a test";
117    std::vector<uint8_t> plainText(message.begin(), message.end());
118    std::vector<uint8_t> cipherText = doTestSm2Enc(keyPair, plainText);
119    std::vector<uint8_t> decryptText = doTestSm2Dec(keyPair, cipherText);
120
121    if ((plainText.size() != decryptText.size()) ||
122        (!std::equal(plainText.begin(), plainText.end(), decryptText.begin()))) {
123        OH_CryptoKeyPair_Destroy(keyPair);
124        OH_CryptoAsymKeyGenerator_Destroy(keyGen);
125        return CRYPTO_OPERTION_ERROR;
126    }
127
128    OH_CryptoKeyPair_Destroy(keyPair);
129    OH_CryptoAsymKeyGenerator_Destroy(keyGen);
130    return CRYPTO_SUCCESS;
131}
132```