• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Signing and Signature Verification by Segment with an RSA Key Pair (PKCS1 Mode) (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 [RSA](crypto-sign-sig-verify-overview.md#rsa).
11
12## Adding the Dynamic Library in the CMake Script
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16## Signing Data
171. Call [OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create) and specify the string parameter **'RSA1024|PKCS1|SHA256'** to create a **Sign** instance for signing.
18
192. Call [OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init) to initialize the **Sign** instance by using the private key (**OH_CryptoPrivKey**).
20
213. 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 **update** is not limited. You can determine how to pass in data based on the data volume. If the data size is small, you can simply call **OH_CryptoSign_Final** to pass in the full data.
22
234. Call [OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final) to obtain the signed data.
24
255. Call [OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy) to free the memory.
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## Verifying the Signature
109
1101. Call [OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create) with the string parameter **'RSA1024|PKCS1|SHA256'** to create a **Verify** instance. The string parameter must be the same as that used to create the **Sign** instance.
111
1122. 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**).
113
1143. 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()**.
115
1164. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature.
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