• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Signing and Signature Verification with an ECDSA 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 [ECDSA](crypto-sign-sig-verify-overview.md#ecdsa).
11
12## Adding the Dynamic Library in the CMake Script
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16
17## Signing Data
181. Call [OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create) with the string parameter **'RSA2048|PSS|SHA256|MGF1_SHA256'** to create a **Sign** instance. As indicated by the string parameter, the asymmetric key type is **RSA2048**, the padding mode is **PSS**, the MD algorithm is **SHA256**, and mask algorithm is **MGF1_SHA256**.
19
202. Call [OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init) to initialize the **Sign** instance using [OH_CryptoPrivKey](../../reference/apis-crypto-architecture-kit/capi-cryptoasymkeyapi-oh-cryptoprivkey.md).
21
223. Call [OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update) to pass in the data to be signed. Currently, the amount of data to be passed in by a single **OH_CryptoVerify_Update** is not limited. You can determine how to pass in data based on the data volume. If a small amount of data is to be verified, you can directly call **OH_CryptoSign_Final** after **OH_CryptoVerify_Init()**.
23
244. Call [OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final) to sign the data.
25
265. Call [OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy) to free the memory.
27
28```c++
29#include "CryptoArchitectureKit/crypto_common.h"
30#include "CryptoArchitectureKit/crypto_signature.h"
31#include "CryptoArchitectureKit/crypto_asym_key.h"
32
33static OH_Crypto_ErrCode doTestRsaPssSignSeg() {
34   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
35   OH_CryptoKeyPair *keyPair = nullptr;
36   OH_CryptoSign *sign = nullptr;
37   Crypto_DataBlob signData = {.data = nullptr, .len = 0};
38
39   uint8_t plainText[] = {
40      0xe4, 0x2b, 0xcc, 0x08, 0x11, 0x79, 0x16, 0x1b, 0x35, 0x7f, 0xb3, 0xaf, 0x40, 0x3b, 0x3f, 0x7c
41   }; // Data to be signed, for reference only.
42   Crypto_DataBlob msgBlob = {
43      .data = reinterpret_cast<uint8_t *>(plainText),
44      .len = sizeof(plainText)
45   };
46
47   OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"ECC256", &keyCtx);
48   if (ret != CRYPTO_SUCCESS) {
49      return ret;
50   }
51   ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair);
52   if (ret != CRYPTO_SUCCESS) {
53      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
54      return ret;
55   }
56
57   OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair);
58   ret = OH_CryptoSign_Create((const char *)"ECC256|SHA256", &sign);
59   if (ret != CRYPTO_SUCCESS) {
60      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
61      OH_CryptoKeyPair_Destroy(keyPair);
62      return ret;
63   }
64
65   ret = OH_CryptoSign_Init(sign, privKey);
66   if (ret != CRYPTO_SUCCESS) {
67      OH_CryptoSign_Destroy(sign);
68      OH_CryptoKeyPair_Destroy(keyPair);
69      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
70      return ret;
71   }
72   ret = OH_CryptoSign_Update(sign, &msgBlob);
73   if (ret != CRYPTO_SUCCESS) {
74      OH_CryptoSign_Destroy(sign);
75      OH_CryptoKeyPair_Destroy(keyPair);
76      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
77      return ret;
78   }
79   ret = OH_CryptoSign_Final(sign, nullptr, &signData);
80   if (ret != CRYPTO_SUCCESS) {
81      OH_CryptoSign_Destroy(sign);
82      OH_CryptoKeyPair_Destroy(keyPair);
83      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
84      return ret;
85   }
86
87   OH_CryptoSign_Destroy(sign);
88   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
89   OH_CryptoKeyPair_Destroy(keyPair);
90   return CRYPTO_SUCCESS;
91}
92```
93
94## Verifying the Signature
95
961. Call [OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create) with the string parameter **'ECC256|SHA256'** to create a **Verify** instance. The key type is **ECC256**, and MD algorithm is **SHA256**.
97
982. Call [OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init) to initialize the **Verify** instance by using the public key (**OH_CryptoPubKey**).
99
1003. Call [OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update) to pass in the data to be verified. Currently, the amount of data to be passed in by a single **OH_CryptoVerify_Update** is not limited. You can determine how to pass in data based on the data volume. If a small amount of data is to be verified, you can call **OH_CryptoVerify_Final** immediately after **OH_CryptoVerify_Init()**.
101
1024. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature.
103
104```c++
105#include "CryptoArchitectureKit/crypto_common.h"
106#include "CryptoArchitectureKit/crypto_signature.h"
107#include "CryptoArchitectureKit/crypto_asym_key.h"
108
109static bool doTestEcdsaSignature()
110{
111   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
112   OH_CryptoKeyPair *keyPair = nullptr;
113   OH_CryptoVerify *verify = nullptr;
114
115   uint8_t plainText[] = {
116      0xe4, 0x2b, 0xcc, 0x08, 0x11, 0x79, 0x16, 0x1b, 0x35, 0x7f, 0xb3, 0xaf, 0x40, 0x3b, 0x3f, 0x7c
117   }; // Data to be verified, for reference only.
118   Crypto_DataBlob msgBlob = {
119      .data = reinterpret_cast<uint8_t *>(plainText),
120      .len = sizeof(plainText)
121   };
122
123   uint8_t pubKeyText[] = {
124      0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
125      0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x22, 0x00, 0x03, 0x4d, 0xe4, 0xbb, 0x11, 0x10,
126      0x1a, 0xd2, 0x05, 0x74, 0xf1, 0x0b, 0xb4, 0x75, 0x57, 0xf4, 0x3e, 0x55, 0x14, 0x17, 0x05, 0x4a,
127      0xb2, 0xfb, 0x8c, 0x84, 0x64, 0x38, 0x02, 0xa0, 0x2a, 0xa6, 0xf0
128   }; // Public key in DER format, for reference only.
129
130   Crypto_DataBlob keyBlob = {
131      .data = reinterpret_cast<uint8_t *>(pubKeyText),
132      .len = sizeof(pubKeyText)
133   };
134
135   uint8_t signText[] = {
136      0x30, 0x44, 0x02, 0x20, 0x21, 0x89, 0x99, 0xb1, 0x56, 0x4e, 0x3a, 0x2c, 0x16, 0x08, 0xb5, 0x8a,
137      0x06, 0x6f, 0x67, 0x47, 0x1b, 0x04, 0x18, 0x7d, 0x53, 0x2d, 0xba, 0x00, 0x38, 0xd9, 0xe3, 0xe7,
138      0x8c, 0xcf, 0x76, 0x83, 0x02, 0x20, 0x13, 0x54, 0x84, 0x9d, 0x73, 0x40, 0xc3, 0x92, 0x66, 0xdc,
139      0x3e, 0xc9, 0xf1, 0x4c, 0x33, 0x84, 0x2a, 0x76, 0xaf, 0xc6, 0x61, 0x84, 0x5c, 0xae, 0x4b, 0x0d,
140      0x3c, 0xb0, 0xc8, 0x04, 0x89, 0x71
141   }; // Signature data, for reference only.
142
143   Crypto_DataBlob signBlob = {
144      .data = reinterpret_cast<uint8_t *>(signText),
145      .len = sizeof(signText)
146   };
147
148   OH_Crypto_ErrCode ret = CRYPTO_SUCCESS;
149
150   ret = OH_CryptoAsymKeyGenerator_Create((const char *)"ECC256", &keyCtx);
151   if (ret != CRYPTO_SUCCESS) {
152      return false;
153   }
154   ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_DER, &keyBlob, nullptr, &keyPair); // Convert the public key in DER format to OH_CryptoKeyPair.
155   if (ret != CRYPTO_SUCCESS) {
156      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
157      return false;
158   }
159   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // Obtain the public key object.
160   // verify
161   ret = OH_CryptoVerify_Create((const char *)"ECC256|SHA256", &verify); // Create a Verify instance.
162   if (ret != CRYPTO_SUCCESS) {
163      OH_CryptoVerify_Destroy(verify);
164      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
165      return false;
166   }
167   ret = OH_CryptoVerify_Init(verify, pubKey);
168   if (ret != CRYPTO_SUCCESS) {
169      OH_CryptoVerify_Destroy(verify);
170      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
171      return false;
172   }
173   bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob);
174   if (res != true) {
175      OH_CryptoVerify_Destroy(verify);
176      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
177      return false;
178   }
179
180   OH_CryptoVerify_Destroy(verify);
181   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
182   OH_CryptoKeyPair_Destroy(keyPair);
183   return res;
184}
185```
186