• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用ECDSA密钥对签名验签 (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对应的算法规格请查看[签名验签算法规格:ECDSA](crypto-sign-sig-verify-overview.md#ecdsa)。
11
12## 在CMake脚本中链接相关动态库
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16
17## 签名开发步骤
181. 调用[OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create),指定字符串参数'RSA2048|PSS|SHA256|MGF1_SHA256',创建非对称密钥类型为RSA2048、填充模式为PSS、摘要算法为SHA256、掩码算法为MGF1_SHA256的Sign实例,用于完成签名操作。
19
202. 调用[OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init),使用私钥[OH_CryptoPrivKey](../../reference/apis-crypto-architecture-kit/capi-cryptoasymkeyapi-oh-cryptoprivkey.md)初始化Sign实例。
21
223. 调用[OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoSign_Final接口一次性传入。
23
244. 调用[OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final),对数据进行签名。
25
265. 调用[OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy)等释放内存。
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   }; // 待签名数据,仅供参考。
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## 验签开发步骤
95
961. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'ECC256|SHA256',创建非对称密钥类型为ECC256、摘要算法为SHA256的Verify实例,用于完成验签操作。
97
982. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。
99
1003. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。
101
1024. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。
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   }; // 待验证数据,仅供参考。
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   }; // DER格式的公钥编码数据,仅供参考。
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   }; // 签名数据,仅供参考。
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); // 将DER格式的公钥编码数据转换为OH_CryptoKeyPair。
155   if (ret != CRYPTO_SUCCESS) {
156      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
157      return false;
158   }
159   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // 获取公钥对象。
160   // verify
161   ret = OH_CryptoVerify_Create((const char *)"ECC256|SHA256", &verify); // 创建Verify实例。
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