• 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_signature.h"
30#include "CryptoArchitectureKit/crypto_asym_key.h"
31
32static OH_Crypto_ErrCode doTestRsaSignature() {
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   ret = OH_CryptoSign_Init(sign, privKey);
68   if (ret != CRYPTO_SUCCESS) {
69      OH_CryptoSign_Destroy(sign);
70      OH_CryptoKeyPair_Destroy(keyPair);
71      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
72      return ret;
73   }
74   ret = OH_CryptoSign_Update(sign, &msgBlob);
75   if (ret != CRYPTO_SUCCESS) {
76      OH_CryptoSign_Destroy(sign);
77      OH_CryptoKeyPair_Destroy(keyPair);
78      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
79      return ret;
80   }
81   ret = OH_CryptoSign_Final(sign, nullptr, &signData);
82   if (ret != CRYPTO_SUCCESS) {
83      OH_CryptoSign_Destroy(sign);
84      OH_CryptoKeyPair_Destroy(keyPair);
85      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
86      return ret;
87   }
88
89   OH_CryptoSign_Destroy(sign);
90   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
91   OH_CryptoKeyPair_Destroy(keyPair);
92   return CRYPTO_SUCCESS;
93}
94```
95
96## 验签开发步骤
97
981. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'RSA1024|PKCS1|SHA256',与签名的Sign实例保持一致。创建Verify实例,用于完成验签操作。
99
1002. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。
101
1023. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。
103   当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。
104
105   - 当待签名的数据较短时,可以在init完成后直接调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final)。
106   - 当数据量较大时,可以多次调用update,即[分段验签](crypto-rsa-sign-sig-verify-pkcs1-by-segment-ndk.md)。
107
1084. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。
109
110```c++
111#include "CryptoArchitectureKit/crypto_common.h"
112#include "CryptoArchitectureKit/crypto_asym_key.h"
113#include "CryptoArchitectureKit/crypto_signature.h"
114
115static bool doTestRsaSignature()
116{
117   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
118   OH_CryptoKeyPair *keyPair = nullptr;
119   OH_CryptoVerify *verify = nullptr;
120
121   uint8_t plainText[] = {
122      0x43, 0x31, 0x7d, 0xb5, 0x85, 0x2e, 0xd4, 0xef, 0x08, 0x7a, 0x17, 0x96, 0xbc, 0x7c, 0x8f, 0x80,
123      0x8c, 0xa7, 0x63, 0x7f, 0x26, 0x89, 0x8f, 0xf0, 0xfa, 0xa7, 0x51, 0xbd, 0x9c, 0x69, 0x17, 0xf3,
124      0xd1, 0xb5, 0xc7, 0x12, 0xbf, 0xcf, 0x91, 0x25, 0x82, 0x23, 0x6b, 0xd6, 0x64, 0x52, 0x77, 0x93,
125      0x01, 0x9d, 0x70, 0xa3, 0xf4, 0x92, 0x16, 0xec, 0x3f, 0xa7, 0x3c, 0x83, 0x8d, 0x40, 0x41, 0xfc,
126   }; // 待验证数据,仅供参考。
127   Crypto_DataBlob msgBlob = {
128      .data = reinterpret_cast<uint8_t *>(plainText),
129      .len = sizeof(plainText)
130   };
131
132   uint8_t pubKeyText[] = {
133      0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50,
134      0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
135      0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4d, 0x78, 0x63, 0x44, 0x4d, 0x6f, 0x61, 0x59,
136      0x52, 0x58, 0x6f, 0x78, 0x65, 0x69, 0x33, 0x49, 0x6d, 0x33, 0x33, 0x78, 0x4a, 0x76, 0x61, 0x73,
137      0x63, 0x43, 0x62, 0x77, 0x31, 0x6f, 0x73, 0x63, 0x32, 0x56, 0x56, 0x69, 0x47, 0x6a, 0x56, 0x47,
138      0x47, 0x4a, 0x37, 0x6c, 0x75, 0x4e, 0x41, 0x58, 0x6b, 0x6a, 0x73, 0x56, 0x46, 0x64, 0x35, 0x0a,
139      0x58, 0x37, 0x4c, 0x4d, 0x6c, 0x46, 0x34, 0x63, 0x35, 0x5a, 0x75, 0x59, 0x2f, 0x61, 0x69, 0x57,
140      0x77, 0x70, 0x54, 0x69, 0x63, 0x62, 0x67, 0x49, 0x33, 0x43, 0x66, 0x50, 0x6f, 0x32, 0x6a, 0x6c,
141      0x52, 0x74, 0x67, 0x41, 0x46, 0x6b, 0x44, 0x71, 0x7a, 0x4b, 0x53, 0x46, 0x62, 0x46, 0x47, 0x51,
142      0x6b, 0x43, 0x6e, 0x64, 0x63, 0x2b, 0x54, 0x59, 0x6b, 0x5a, 0x42, 0x32, 0x70, 0x45, 0x6f, 0x72,
143      0x0a, 0x7a, 0x73, 0x61, 0x56, 0x58, 0x77, 0x5a, 0x47, 0x45, 0x34, 0x41, 0x43, 0x70, 0x59, 0x35,
144      0x79, 0x65, 0x66, 0x49, 0x44, 0x6c, 0x45, 0x57, 0x49, 0x51, 0x4f, 0x6a, 0x59, 0x4b, 0x2f, 0x6c,
145      0x58, 0x71, 0x7a, 0x48, 0x47, 0x69, 0x4f, 0x69, 0x32, 0x75, 0x4a, 0x45, 0x75, 0x44, 0x43, 0x50,
146      0x6a, 0x51, 0x64, 0x6a, 0x54, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x3d, 0x0a, 0x2d, 0x2d,
147      0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49,
148      0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
149   }; // 公钥DER编码数据,仅供参考。
150
151   Crypto_DataBlob keyBlob = {
152      .data = reinterpret_cast<uint8_t *>(pubKeyText),
153      .len = sizeof(pubKeyText)
154   };
155
156   uint8_t signText[] = {
157      0x68, 0x2f, 0x3b, 0xe6, 0xa6, 0x5c, 0xb8, 0x60, 0xd4, 0xe1, 0x64, 0xa7, 0xd8, 0x0c, 0x9c, 0x89,
158      0x39, 0xb4, 0xf0, 0xb7, 0xad, 0xb5, 0x8a, 0x71, 0x04, 0xf1, 0xa5, 0x63, 0xdd, 0x32, 0x6a, 0x44,
159      0xeb, 0xff, 0xb7, 0xe6, 0x85, 0xe5, 0xa5, 0x55, 0x5d, 0x5b, 0x28, 0x53, 0x63, 0xe4, 0xb3, 0xb9,
160      0xa8, 0x70, 0xc8, 0x8f, 0xcd, 0x21, 0x8d, 0xe6, 0x1f, 0xe5, 0x78, 0x34, 0xd3, 0x45, 0x0c, 0x9c,
161      0x7a, 0x22, 0x1b, 0x63, 0x55, 0xca, 0x14, 0xa5, 0x0c, 0x7a, 0x40, 0x8e, 0xa1, 0x14, 0x78, 0xa1,
162      0xf1, 0x36, 0x78, 0xbd, 0xba, 0x37, 0x3b, 0x5b, 0xb0, 0x8e, 0xb3, 0x4a, 0x9b, 0x1b, 0x0c, 0xfa,
163      0xfa, 0xc7, 0x9f, 0xb1, 0x35, 0x48, 0x82, 0x73, 0xf8, 0x6b, 0xd4, 0x76, 0x33, 0x5c, 0xed, 0x9c,
164      0xd8, 0x4b, 0xc9, 0x92, 0xa0, 0x3f, 0x6e, 0xba, 0x78, 0x2e, 0x80, 0x78, 0x1e, 0x74, 0xa0, 0x47,
165   }; // 签名数据,仅供参考。
166
167   Crypto_DataBlob signBlob = {
168      .data = reinterpret_cast<uint8_t *>(signText),
169      .len = sizeof(signText)
170   };
171
172   // keypair
173   OH_Crypto_ErrCode ret = CRYPTO_SUCCESS;
174   ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx); // 创建非对称密钥生成器。
175   if (ret != CRYPTO_SUCCESS) {
176      return false;
177   }
178   ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair); // 将PEM格式的公钥编码数据转换为OH_CryptoKeyPair。
179   if (ret != CRYPTO_SUCCESS) {
180      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
181      return false;
182   }
183   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // 获取公钥。
184   // verify
185   ret = OH_CryptoVerify_Create((const char *)"RSA1024|PKCS1|SHA256", &verify); // 创建Verify实例。
186   if (ret != CRYPTO_SUCCESS) {
187      OH_CryptoVerify_Destroy(verify);
188      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
189      return false;
190   }
191   ret = OH_CryptoVerify_Init(verify, pubKey); // 使用公钥初始化Verify实例。
192   if (ret != CRYPTO_SUCCESS) {
193      OH_CryptoVerify_Destroy(verify);
194      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
195      return false;
196   }
197   bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob); // 对数据进行验签。
198   if (res != true) {
199      OH_CryptoVerify_Destroy(verify);
200      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
201      return false;
202   }
203
204   OH_CryptoVerify_Destroy(verify);
205   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
206   OH_CryptoKeyPair_Destroy(keyPair);
207   return res;
208}
209```
210