1# Signing and Signature Verification 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_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 }; // Data to be verified, for reference only. 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## Verifying the Signature 97 981. 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. 99 1002. 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**). 101 1023. 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. 103 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. 104 105 - If a small amount of data is to be verified, you can directly call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) after **OH_CryptoVerify_Init()**. 106 - If a large amount of data is to be verified, call **OH_CryptoVerify_Update()** multiple times to [pass in data by segment](crypto-rsa-sign-sig-verify-pkcs1-by-segment-ndk.md). 107 1084. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature. 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 }; // Data to be verified, for reference only. 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 }; // Public key in DER format, for reference only. 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 }; // Signature data, for reference only. 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); // Create an asymmetric key generator. 175 if (ret != CRYPTO_SUCCESS) { 176 return false; 177 } 178 ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair); // Convert the public key in PEM format to OH_CryptoKeyPair. 179 if (ret != CRYPTO_SUCCESS) { 180 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 181 return false; 182 } 183 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // Obtain the public key. 184 // verify 185 ret = OH_CryptoVerify_Create((const char *)"RSA1024|PKCS1|SHA256", &verify); // Create a Verify instance. 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); // Use the public key to initialize the Verify instance. 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); // Verify the signature of the data. 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