• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用RSA密钥对分段签名验签 (PKCS1模式)(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对应的算法规格请查看[签名验签算法规格:RSA](crypto-sign-sig-verify-overview.md#rsa)。
11
12## 在CMake脚本中链接相关动态库
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16## 签名开发步骤
171. 调用[OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create),指定字符串参数'RSA1024|PKCS1|SHA256',创建Sign实例,用于完成签名操作。
18
192. 调用[OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init),使用私钥(OH_CryptoPrivKey)初始化Sign实例。
20
213. 调用[OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。如果数据量较小,可以直接调用OH_CryptoSign_Final接口一次性传入。
22
234. 调用[OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final),获取签名后的数据。
24
255. 调用[OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy)等释放内存。
26
27```c++
28#include "CryptoArchitectureKit/crypto_common.h"
29#include "CryptoArchitectureKit/crypto_asym_key.h"
30#include "CryptoArchitectureKit/crypto_signature.h"
31
32static OH_Crypto_ErrCode doTestRsaSignSeg() {
33   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
34   OH_CryptoKeyPair *keyPair = nullptr;
35   OH_CryptoSign *sign = nullptr;
36   Crypto_DataBlob signData = {.data = nullptr, .len = 0};
37
38   uint8_t plainText[] = {
39      0x43, 0x31, 0x7d, 0xb5, 0x85, 0x2e, 0xd4, 0xef, 0x08, 0x7a, 0x17, 0x96, 0xbc, 0x7c, 0x8f, 0x80,
40      0x8c, 0xa7, 0x63, 0x7f, 0x26, 0x89, 0x8f, 0xf0, 0xfa, 0xa7, 0x51, 0xbd, 0x9c, 0x69, 0x17, 0xf3,
41      0xd1, 0xb5, 0xc7, 0x12, 0xbf, 0xcf, 0x91, 0x25, 0x82, 0x23, 0x6b, 0xd6, 0x64, 0x52, 0x77, 0x93,
42      0x01, 0x9d, 0x70, 0xa3, 0xf4, 0x92, 0x16, 0xec, 0x3f, 0xa7, 0x3c, 0x83, 0x8d, 0x40, 0x41, 0xfc,
43   };
44   Crypto_DataBlob msgBlob = {
45      .data = reinterpret_cast<uint8_t *>(plainText),
46      .len = sizeof(plainText)
47   };
48
49   OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx);
50   if (ret != CRYPTO_SUCCESS) {
51      return ret;
52   }
53   ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair);
54   if (ret != CRYPTO_SUCCESS) {
55      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
56      return ret;
57   }
58
59   OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair);
60   ret = OH_CryptoSign_Create((const char *)"RSA1024|PKCS1|SHA256", &sign);
61   if (ret != CRYPTO_SUCCESS) {
62      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
63      OH_CryptoKeyPair_Destroy(keyPair);
64      return ret;
65   }
66
67   int blockSize = 20;
68   int cnt_s = 64 / blockSize;
69   int rem_s = 64 % blockSize;
70   ret = OH_CryptoSign_Init(sign, privKey);
71   if (ret != CRYPTO_SUCCESS) {
72      OH_CryptoSign_Destroy(sign);
73      OH_CryptoKeyPair_Destroy(keyPair);
74      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
75      return ret;
76   }
77   for (int i = 0; i < cnt_s; i++) {
78      msgBlob.len = blockSize;
79      ret = OH_CryptoSign_Update(sign, &msgBlob);
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      msgBlob.data += blockSize;
87   }
88   if (rem_s > 0) {
89      msgBlob.len = rem_s;
90      ret = OH_CryptoSign_Final(sign, &msgBlob, &signData);
91      if (ret != CRYPTO_SUCCESS) {
92         OH_CryptoSign_Destroy(sign);
93         OH_CryptoKeyPair_Destroy(keyPair);
94         OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
95         return ret;
96      }
97   }
98
99   msgBlob.data -=  64 - rem_s;
100   msgBlob.len = 64;
101   OH_CryptoSign_Destroy(sign);
102   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
103   OH_CryptoKeyPair_Destroy(keyPair);
104   return CRYPTO_SUCCESS;
105}
106```
107
108## 验签开发步骤
109
1101. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'RSA1024|PKCS1|SHA256',与签名的Sign实例保持一致。创建Verify实例,用于完成验签操作。
111
1122. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。
113
1143. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。
115
1164. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。
117
118```c++
119#include "CryptoArchitectureKit/crypto_common.h"
120#include "CryptoArchitectureKit/crypto_asym_key.h"
121#include "CryptoArchitectureKit/crypto_signature.h"
122
123static bool doTestRsaSignatureSeg()
124{
125   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
126   OH_CryptoKeyPair *keyPair = nullptr;
127   OH_CryptoVerify *verify = nullptr;
128
129   uint8_t plainText[] = {
130      0x43, 0x31, 0x7d, 0xb5, 0x85, 0x2e, 0xd4, 0xef, 0x08, 0x7a, 0x17, 0x96, 0xbc, 0x7c, 0x8f, 0x80,
131      0x8c, 0xa7, 0x63, 0x7f, 0x26, 0x89, 0x8f, 0xf0, 0xfa, 0xa7, 0x51, 0xbd, 0x9c, 0x69, 0x17, 0xf3,
132      0xd1, 0xb5, 0xc7, 0x12, 0xbf, 0xcf, 0x91, 0x25, 0x82, 0x23, 0x6b, 0xd6, 0x64, 0x52, 0x77, 0x93,
133      0x01, 0x9d, 0x70, 0xa3, 0xf4, 0x92, 0x16, 0xec, 0x3f, 0xa7, 0x3c, 0x83, 0x8d, 0x40, 0x41, 0xfc,
134   };
135   Crypto_DataBlob msgBlob = {
136      .data = reinterpret_cast<uint8_t *>(plainText),
137      .len = sizeof(plainText)
138   };
139
140   uint8_t pubKeyText[] = {
141      0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50,
142      0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
143      0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4d, 0x78, 0x63, 0x44, 0x4d, 0x6f, 0x61, 0x59,
144      0x52, 0x58, 0x6f, 0x78, 0x65, 0x69, 0x33, 0x49, 0x6d, 0x33, 0x33, 0x78, 0x4a, 0x76, 0x61, 0x73,
145      0x63, 0x43, 0x62, 0x77, 0x31, 0x6f, 0x73, 0x63, 0x32, 0x56, 0x56, 0x69, 0x47, 0x6a, 0x56, 0x47,
146      0x47, 0x4a, 0x37, 0x6c, 0x75, 0x4e, 0x41, 0x58, 0x6b, 0x6a, 0x73, 0x56, 0x46, 0x64, 0x35, 0x0a,
147      0x58, 0x37, 0x4c, 0x4d, 0x6c, 0x46, 0x34, 0x63, 0x35, 0x5a, 0x75, 0x59, 0x2f, 0x61, 0x69, 0x57,
148      0x77, 0x70, 0x54, 0x69, 0x63, 0x62, 0x67, 0x49, 0x33, 0x43, 0x66, 0x50, 0x6f, 0x32, 0x6a, 0x6c,
149      0x52, 0x74, 0x67, 0x41, 0x46, 0x6b, 0x44, 0x71, 0x7a, 0x4b, 0x53, 0x46, 0x62, 0x46, 0x47, 0x51,
150      0x6b, 0x43, 0x6e, 0x64, 0x63, 0x2b, 0x54, 0x59, 0x6b, 0x5a, 0x42, 0x32, 0x70, 0x45, 0x6f, 0x72,
151      0x0a, 0x7a, 0x73, 0x61, 0x56, 0x58, 0x77, 0x5a, 0x47, 0x45, 0x34, 0x41, 0x43, 0x70, 0x59, 0x35,
152      0x79, 0x65, 0x66, 0x49, 0x44, 0x6c, 0x45, 0x57, 0x49, 0x51, 0x4f, 0x6a, 0x59, 0x4b, 0x2f, 0x6c,
153      0x58, 0x71, 0x7a, 0x48, 0x47, 0x69, 0x4f, 0x69, 0x32, 0x75, 0x4a, 0x45, 0x75, 0x44, 0x43, 0x50,
154      0x6a, 0x51, 0x64, 0x6a, 0x54, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x3d, 0x0a, 0x2d, 0x2d,
155      0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
156      0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
157   };
158
159   Crypto_DataBlob keyBlob = {
160      .data = reinterpret_cast<uint8_t *>(pubKeyText),
161      .len = sizeof(pubKeyText)
162   };
163
164   uint8_t signText[] = {
165      0x68, 0x2f, 0x3b, 0xe6, 0xa6, 0x5c, 0xb8, 0x60, 0xd4, 0xe1, 0x64, 0xa7, 0xd8, 0x0c, 0x9c, 0x89,
166      0x39, 0xb4, 0xf0, 0xb7, 0xad, 0xb5, 0x8a, 0x71, 0x04, 0xf1, 0xa5, 0x63, 0xdd, 0x32, 0x6a, 0x44,
167      0xeb, 0xff, 0xb7, 0xe6, 0x85, 0xe5, 0xa5, 0x55, 0x5d, 0x5b, 0x28, 0x53, 0x63, 0xe4, 0xb3, 0xb9,
168      0xa8, 0x70, 0xc8, 0x8f, 0xcd, 0x21, 0x8d, 0xe6, 0x1f, 0xe5, 0x78, 0x34, 0xd3, 0x45, 0x0c, 0x9c,
169      0x7a, 0x22, 0x1b, 0x63, 0x55, 0xca, 0x14, 0xa5, 0x0c, 0x7a, 0x40, 0x8e, 0xa1, 0x14, 0x78, 0xa1,
170      0xf1, 0x36, 0x78, 0xbd, 0xba, 0x37, 0x3b, 0x5b, 0xb0, 0x8e, 0xb3, 0x4a, 0x9b, 0x1b, 0x0c, 0xfa,
171      0xfa, 0xc7, 0x9f, 0xb1, 0x35, 0x48, 0x82, 0x73, 0xf8, 0x6b, 0xd4, 0x76, 0x33, 0x5c, 0xed, 0x9c,
172      0xd8, 0x4b, 0xc9, 0x92, 0xa0, 0x3f, 0x6e, 0xba, 0x78, 0x2e, 0x80, 0x78, 0x1e, 0x74, 0xa0, 0x47,
173   };
174
175   Crypto_DataBlob signBlob = {
176      .data = reinterpret_cast<uint8_t *>(signText),
177      .len = sizeof(signText)
178   };
179
180   // keypair
181   OH_Crypto_ErrCode ret = CRYPTO_SUCCESS;
182   ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx);
183   if (ret != CRYPTO_SUCCESS) {
184      return false;
185   }
186   ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair);
187   if (ret != CRYPTO_SUCCESS) {
188      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
189      return false;
190   }
191   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair);
192   // verify
193   ret = OH_CryptoVerify_Create((const char *)"RSA1024|PKCS1|SHA256", &verify);
194   if (ret != CRYPTO_SUCCESS) {
195      OH_CryptoVerify_Destroy(verify);
196      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
197      return false;
198   }
199   int blockSize = 20;
200   int cnt_s = 64 / blockSize;
201   int rem_s = 64 % blockSize;
202   ret = OH_CryptoVerify_Init(verify, pubKey);
203   if (ret != CRYPTO_SUCCESS) {
204      OH_CryptoVerify_Destroy(verify);
205      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
206      return false;
207   }
208   for (int i = 0; i < cnt_s; i++) {
209      msgBlob.len = blockSize;
210      ret = OH_CryptoVerify_Update(verify, (Crypto_DataBlob *)&msgBlob);
211      if (ret != CRYPTO_SUCCESS) {
212         OH_CryptoVerify_Destroy(verify);
213         OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
214         return false;
215      }
216      msgBlob.data += blockSize;
217   }
218   bool res = false;
219   if (rem_s > 0) {
220      msgBlob.len = rem_s;
221      res = OH_CryptoVerify_Final(verify, (Crypto_DataBlob *)&msgBlob, (Crypto_DataBlob *)&signBlob);
222      if (res != true) {
223         OH_CryptoVerify_Destroy(verify);
224         OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
225         return false;
226      }
227   }
228
229   msgBlob.data -=  64 - rem_s;
230   msgBlob.len = 64;
231
232   OH_CryptoVerify_Destroy(verify);
233   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
234   OH_CryptoKeyPair_Destroy(keyPair);
235   return res;
236}
237```
238