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