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