• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Encryption and Decryption with an SM2 Asymmetric Key Pair (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
10For details about the algorithm specifications, see [SM2](crypto-asym-encrypt-decrypt-spec.md#sm2).
11
12**Encryption**
13
141. Call [OH_CryptoAsymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygenerator_create) and [OH_CryptoAsymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-key-h.md#oh_cryptoasymkeygenerator_generate) to generate an asymmetric key pair (**keyPair**) of the SM2_256 type. The **keyPair** object includes a public key (**PubKey**) and a private key (**PriKey**).
15
16   For details about how to generate an SM2 asymmetric key pair, see the following example. To learn more, see [SM2](crypto-asym-key-generation-conversion-spec.md#sm2) and [Randomly Generating an Asymmetric Key Pair](crypto-generate-asym-key-pair-randomly-ndk.md). There may be differences between the input parameters in the reference documents and those in the following example.
17
182. Call [OH_CryptoAsymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_create) with the string parameter **'SM2_256|SM3'** to create a **Cipher** instance for encryption. The key type is **SM2_256**, and the digest algorithm is **SM3**.
19
203. Call [OH_CryptoAsymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_ENCRYPT_MODE**, and specify the key for encryption (**keyPair**).
21
224. Call [OH_CryptoAsymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_final) and pass the plaintext to obtain the encrypted data.
23
24   The output of **OH_CryptoAsymCipher_Final** may be **NULL**. To avoid exceptions, always check whether the result is **NULL** before accessing specific data.
25
26**Decryption**
27
281. If SM2 is used, the **Cipher** instance cannot be initialized repeatedly. Call [OH_CryptoAsymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_create) to create a new **Cipher** instance.
29
302. Call [OH_CryptoAsymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_DECRYPT_MODE**, and specify the key for decryption (**keyPair**).
31
323. Call [OH_CryptoAsymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-asym-cipher-h.md#oh_cryptoasymcipher_final) and pass the ciphertext to obtain the decrypted data.
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```
133