• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Signing and Signature Verification with an RSA Key Pair (PSS 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) 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**.
182. 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**).
193. 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.
204. Call [OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final) to obtain the signed data.
215. Call [OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy) to free the memory.
22
23```c++
24#include "CryptoArchitectureKit/crypto_common.h"
25#include "CryptoArchitectureKit/crypto_signature.h"
26#include "CryptoArchitectureKit/crypto_asym_key.h"
27
28static OH_Crypto_ErrCode doTestRsaPssSignSeg() {
29   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
30   OH_CryptoKeyPair *keyPair = nullptr;
31   OH_CryptoSign *sign = nullptr;
32   Crypto_DataBlob signData = {.data = nullptr, .len = 0};
33
34   uint8_t plainText[] = {
35      0x13, 0xa7, 0x73, 0xe8, 0xb8, 0x22, 0x99, 0x72, 0x98, 0x29, 0xae, 0x74, 0xa8, 0x4a, 0xea, 0xa9,
36   };
37   Crypto_DataBlob msgBlob = {
38      .data = reinterpret_cast<uint8_t *>(plainText),
39      .len = sizeof(plainText)
40   };
41
42   OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx);
43   if (ret != CRYPTO_SUCCESS) {
44      return ret;
45   }
46   ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair);
47   if (ret != CRYPTO_SUCCESS) {
48      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
49      return ret;
50   }
51
52   OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair);
53   ret = OH_CryptoSign_Create((const char *)"RSA2048|PSS|SHA256|MGF1_SHA256", &sign);
54   if (ret != CRYPTO_SUCCESS) {
55      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
56      OH_CryptoKeyPair_Destroy(keyPair);
57      return ret;
58   }
59
60   ret = OH_CryptoSign_Init(sign, privKey);
61   if (ret != CRYPTO_SUCCESS) {
62      OH_CryptoSign_Destroy(sign);
63      OH_CryptoKeyPair_Destroy(keyPair);
64      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
65      return ret;
66   }
67   ret = OH_CryptoSign_Update(sign, &msgBlob);
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_Final(sign, nullptr, &signData);
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
82   OH_CryptoSign_Destroy(sign);
83   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
84   OH_CryptoKeyPair_Destroy(keyPair);
85   return CRYPTO_SUCCESS;
86}
87
88```
89
90## How to Develop
91
921. Call [OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create) with the string parameter **'RSA2048|PSS|SHA256|MGF1_SHA256'** to create a **Verify** 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**.
93
942. Call [OH_CryptoVerify_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_setparam) to set parameters. The parameter values must be the same as those set for signing.
95
963. 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**).
97
984. 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 directly call **OH_CryptoVerify_Final** after **OH_CryptoVerify_Init()**.
99
1005. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature.
101
102```c++
103#include "CryptoArchitectureKit/crypto_common.h"
104#include "CryptoArchitectureKit/crypto_signature.h"
105#include "CryptoArchitectureKit/crypto_asym_key.h"
106
107static bool doTestRsaPssSignatureSeg()
108{
109   OH_CryptoAsymKeyGenerator *keyCtx = nullptr;
110   OH_CryptoKeyPair *keyPair = nullptr;
111   OH_CryptoVerify *verify = nullptr;
112
113   uint8_t plainText[] = {
114      0x13, 0xa7, 0x73, 0xe8, 0xb8, 0x22, 0x99, 0x72, 0x98, 0x29, 0xae, 0x74, 0xa8, 0x4a, 0xea, 0xa9,
115   };
116   Crypto_DataBlob msgBlob = {
117      .data = reinterpret_cast<uint8_t *>(plainText),
118      .len = sizeof(plainText)
119   };
120
121   uint8_t pubKeyText[] = {
122      0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50,
123      0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d,
124      0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x76, 0x6a, 0x6c, 0x59, 0x35,
125      0x53, 0x72, 0x54, 0x57, 0x32, 0x43, 0x78, 0x74, 0x47, 0x32, 0x54, 0x67, 0x54, 0x54, 0x39, 0x39,
126      0x78, 0x71, 0x37, 0x62, 0x4e, 0x41, 0x6b, 0x54, 0x2b, 0x65, 0x6a, 0x75, 0x65, 0x7a, 0x37, 0x39,
127      0x37, 0x2f, 0x65, 0x63, 0x56, 0x4b, 0x34, 0x78, 0x37, 0x58, 0x41, 0x4d, 0x6d, 0x73, 0x4a, 0x0a,
128      0x4a, 0x63, 0x66, 0x49, 0x36, 0x73, 0x54, 0x4d, 0x4e, 0x68, 0x45, 0x6b, 0x70, 0x79, 0x63, 0x31,
129      0x4b, 0x32, 0x46, 0x6e, 0x30, 0x74, 0x59, 0x47, 0x2f, 0x6d, 0x4d, 0x37, 0x72, 0x71, 0x6d, 0x6a,
130      0x6c, 0x6b, 0x75, 0x72, 0x34, 0x72, 0x74, 0x6a, 0x4a, 0x4a, 0x75, 0x66, 0x34, 0x35, 0x45, 0x42,
131      0x30, 0x79, 0x6c, 0x55, 0x65, 0x47, 0x61, 0x39, 0x6d, 0x44, 0x4a, 0x57, 0x76, 0x62, 0x2b, 0x73,
132      0x0a, 0x41, 0x4a, 0x78, 0x33, 0x41, 0x44, 0x78, 0x70, 0x50, 0x31, 0x59, 0x36, 0x46, 0x61, 0x71,
133      0x54, 0x44, 0x6e, 0x64, 0x47, 0x41, 0x6e, 0x6b, 0x65, 0x4d, 0x53, 0x2f, 0x56, 0x71, 0x53, 0x45,
134      0x65, 0x75, 0x43, 0x36, 0x4d, 0x42, 0x38, 0x52, 0x53, 0x65, 0x6f, 0x31, 0x4f, 0x59, 0x4c, 0x53,
135      0x73, 0x7a, 0x36, 0x43, 0x76, 0x38, 0x34, 0x76, 0x76, 0x53, 0x69, 0x32, 0x37, 0x32, 0x51, 0x44,
136      0x6e, 0x0a, 0x6f, 0x4b, 0x4f, 0x4d, 0x34, 0x43, 0x78, 0x6d, 0x6e, 0x32, 0x31, 0x58, 0x5a, 0x43,
137      0x5a, 0x2f, 0x59, 0x50, 0x32, 0x35, 0x67, 0x5a, 0x6e, 0x57, 0x4f, 0x61, 0x42, 0x4c, 0x50, 0x57,
138      0x79, 0x6f, 0x48, 0x46, 0x65, 0x49, 0x55, 0x42, 0x48, 0x4c, 0x50, 0x69, 0x4a, 0x2b, 0x72, 0x58,
139      0x48, 0x4e, 0x65, 0x4f, 0x38, 0x2b, 0x70, 0x6c, 0x37, 0x49, 0x42, 0x74, 0x66, 0x35, 0x67, 0x70,
140      0x4a, 0x76, 0x0a, 0x31, 0x6e, 0x78, 0x72, 0x45, 0x4b, 0x73, 0x75, 0x2b, 0x6e, 0x64, 0x48, 0x43,
141      0x6e, 0x46, 0x64, 0x6f, 0x38, 0x2f, 0x49, 0x46, 0x46, 0x4a, 0x6a, 0x70, 0x36, 0x73, 0x6f, 0x55,
142      0x4a, 0x4f, 0x5a, 0x52, 0x4b, 0x6e, 0x6f, 0x41, 0x4b, 0x34, 0x67, 0x6a, 0x34, 0x48, 0x30, 0x50,
143      0x76, 0x49, 0x79, 0x4d, 0x67, 0x4b, 0x61, 0x43, 0x43, 0x41, 0x55, 0x57, 0x70, 0x4a, 0x65, 0x76,
144      0x35, 0x42, 0x52, 0x0a, 0x42, 0x4f, 0x56, 0x38, 0x4f, 0x59, 0x34, 0x48, 0x48, 0x6f, 0x42, 0x6b,
145      0x47, 0x4d, 0x6e, 0x32, 0x71, 0x6a, 0x4d, 0x48, 0x78, 0x49, 0x6c, 0x71, 0x48, 0x50, 0x67, 0x59,
146      0x70, 0x41, 0x53, 0x50, 0x51, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0a, 0x2d, 0x2d, 0x2d,
147      0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43,
148      0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
149   };
150
151   Crypto_DataBlob keyBlob = {
152      .data = reinterpret_cast<uint8_t *>(pubKeyText),
153      .len = sizeof(pubKeyText)
154   };
155
156   uint8_t signText[] = {
157      0xac, 0x2b, 0x12, 0x56, 0x1c, 0xe1, 0x60, 0x49, 0xc2, 0xd9, 0x87, 0x89, 0xfb, 0xa3, 0xc5, 0x41,
158      0x64, 0x7f, 0x6f, 0x80, 0xc8, 0xdb, 0xb3, 0xdf, 0x25, 0x76, 0x4b, 0x1e, 0x51, 0xaa, 0x0a, 0x6d,
159      0x83, 0x49, 0xae, 0x00, 0x7a, 0x99, 0xf4, 0xc8, 0x98, 0x45, 0x71, 0xfc, 0x5e, 0xdb, 0xed, 0x31,
160      0xad, 0xf2, 0x35, 0x05, 0xe2, 0x3e, 0xf1, 0xcb, 0x96, 0xb2, 0xb9, 0x59, 0xaf, 0x30, 0x25, 0xb0,
161      0xda, 0x83, 0x18, 0x2b, 0x11, 0xa4, 0x93, 0x2d, 0x9e, 0x93, 0x99, 0x62, 0xdd, 0xea, 0x1b, 0xfa,
162      0x60, 0xb8, 0xea, 0x9c, 0xef, 0x4f, 0x2b, 0x9d, 0xd1, 0x3e, 0xe1, 0x6b, 0x24, 0x98, 0x9d, 0x32,
163      0xa3, 0x1e, 0x9d, 0x45, 0xe7, 0x3d, 0x51, 0x7e, 0x3b, 0x0c, 0xee, 0x3f, 0xca, 0x29, 0xd9, 0x02,
164      0xe5, 0xb8, 0xf5, 0x89, 0x06, 0xf4, 0xfe, 0x27, 0x44, 0xff, 0x38, 0xed, 0x5a, 0x0e, 0x89, 0x16,
165      0x15, 0x26, 0xf0, 0xb2, 0x4c, 0x95, 0xee, 0x0a, 0xd3, 0x61, 0xc7, 0xb2, 0x4b, 0xfd, 0x20, 0xb9,
166      0x83, 0x25, 0x43, 0x4d, 0xa0, 0x3d, 0xaa, 0x40, 0x7b, 0xac, 0x01, 0x48, 0x8e, 0x2a, 0x96, 0x11,
167      0xc0, 0x31, 0x51, 0x5b, 0xaf, 0xeb, 0x8b, 0xaf, 0xb5, 0x88, 0xcb, 0xe0, 0x97, 0x45, 0x36, 0xe9,
168      0x6e, 0x6e, 0xe0, 0x55, 0xea, 0xf4, 0xd2, 0x88, 0xbb, 0xc9, 0x85, 0x94, 0xd5, 0x65, 0xeb, 0xa3,
169      0x1c, 0xd1, 0xd6, 0xf5, 0x22, 0x29, 0xf1, 0x16, 0xa5, 0x53, 0x1b, 0xd0, 0x6c, 0xf6, 0x0d, 0xa8,
170      0xd4, 0xe4, 0xb2, 0x0a, 0x92, 0x64, 0x7a, 0x6d, 0xf2, 0x76, 0xf3, 0xb0, 0x08, 0x44, 0x31, 0x31,
171      0x90, 0x48, 0x9e, 0x2e, 0x03, 0xc7, 0xab, 0x5d, 0x7a, 0x07, 0x1f, 0x1d, 0x10, 0x21, 0x54, 0x60,
172      0x0d, 0x26, 0xe4, 0x1c, 0xc7, 0x82, 0x03, 0x65, 0x64, 0x70, 0x41, 0x68, 0x0f, 0xfa, 0x64, 0x3c,
173   };
174
175   Crypto_DataBlob signBlob = {
176      .data = reinterpret_cast<uint8_t *>(signText),
177      .len = sizeof(signText)
178   };
179
180   OH_Crypto_ErrCode ret = CRYPTO_SUCCESS;
181   ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx);
182   if (ret != CRYPTO_SUCCESS) {
183      return false;
184   }
185   ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair);
186   if (ret != CRYPTO_SUCCESS) {
187      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
188      return false;
189   }
190   OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair);
191
192   ret = OH_CryptoVerify_Create((const char *)"RSA2048|PSS|SHA256|MGF1_SHA256", &verify);
193   if (ret != CRYPTO_SUCCESS) {
194      OH_CryptoVerify_Destroy(verify);
195      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
196      return false;
197   }
198   ret = OH_CryptoVerify_Init(verify, pubKey);
199   if (ret != CRYPTO_SUCCESS) {
200      OH_CryptoVerify_Destroy(verify);
201      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
202      return false;
203   }
204   bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob);
205   if (res != true) {
206      OH_CryptoVerify_Destroy(verify);
207      OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
208      return false;
209   }
210
211   OH_CryptoVerify_Destroy(verify);
212   OH_CryptoAsymKeyGenerator_Destroy(keyCtx);
213   OH_CryptoKeyPair_Destroy(keyPair);
214   return res;
215}
216```
217