1# Signing and Signature Verification with an ECDSA Key Pair (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 [ECDSA](crypto-sign-sig-verify-overview.md#ecdsa). 11 12## Adding the Dynamic Library in the CMake Script 13```txt 14target_link_libraries(entry PUBLIC libohcrypto.so) 15``` 16 17## Signing Data 181. 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**. 19 202. Call [OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init) to initialize the **Sign** instance using [OH_CryptoPrivKey](../../reference/apis-crypto-architecture-kit/capi-cryptoasymkeyapi-oh-cryptoprivkey.md). 21 223. 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 **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_CryptoSign_Final** after **OH_CryptoVerify_Init()**. 23 244. Call [OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final) to sign the data. 25 265. Call [OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy) to free the memory. 27 28```c++ 29#include "CryptoArchitectureKit/crypto_common.h" 30#include "CryptoArchitectureKit/crypto_signature.h" 31#include "CryptoArchitectureKit/crypto_asym_key.h" 32 33static OH_Crypto_ErrCode doTestRsaPssSignSeg() { 34 OH_CryptoAsymKeyGenerator *keyCtx = nullptr; 35 OH_CryptoKeyPair *keyPair = nullptr; 36 OH_CryptoSign *sign = nullptr; 37 Crypto_DataBlob signData = {.data = nullptr, .len = 0}; 38 39 uint8_t plainText[] = { 40 0xe4, 0x2b, 0xcc, 0x08, 0x11, 0x79, 0x16, 0x1b, 0x35, 0x7f, 0xb3, 0xaf, 0x40, 0x3b, 0x3f, 0x7c 41 }; // Data to be signed, for reference only. 42 Crypto_DataBlob msgBlob = { 43 .data = reinterpret_cast<uint8_t *>(plainText), 44 .len = sizeof(plainText) 45 }; 46 47 OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"ECC256", &keyCtx); 48 if (ret != CRYPTO_SUCCESS) { 49 return ret; 50 } 51 ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair); 52 if (ret != CRYPTO_SUCCESS) { 53 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 54 return ret; 55 } 56 57 OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair); 58 ret = OH_CryptoSign_Create((const char *)"ECC256|SHA256", &sign); 59 if (ret != CRYPTO_SUCCESS) { 60 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 61 OH_CryptoKeyPair_Destroy(keyPair); 62 return ret; 63 } 64 65 ret = OH_CryptoSign_Init(sign, privKey); 66 if (ret != CRYPTO_SUCCESS) { 67 OH_CryptoSign_Destroy(sign); 68 OH_CryptoKeyPair_Destroy(keyPair); 69 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 70 return ret; 71 } 72 ret = OH_CryptoSign_Update(sign, &msgBlob); 73 if (ret != CRYPTO_SUCCESS) { 74 OH_CryptoSign_Destroy(sign); 75 OH_CryptoKeyPair_Destroy(keyPair); 76 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 77 return ret; 78 } 79 ret = OH_CryptoSign_Final(sign, nullptr, &signData); 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 87 OH_CryptoSign_Destroy(sign); 88 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 89 OH_CryptoKeyPair_Destroy(keyPair); 90 return CRYPTO_SUCCESS; 91} 92``` 93 94## Verifying the Signature 95 961. Call [OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create) with the string parameter **'ECC256|SHA256'** to create a **Verify** instance. The key type is **ECC256**, and MD algorithm is **SHA256**. 97 982. 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**). 99 1003. 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()**. 101 1024. Call [OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final) to verify the signature. 103 104```c++ 105#include "CryptoArchitectureKit/crypto_common.h" 106#include "CryptoArchitectureKit/crypto_signature.h" 107#include "CryptoArchitectureKit/crypto_asym_key.h" 108 109static bool doTestEcdsaSignature() 110{ 111 OH_CryptoAsymKeyGenerator *keyCtx = nullptr; 112 OH_CryptoKeyPair *keyPair = nullptr; 113 OH_CryptoVerify *verify = nullptr; 114 115 uint8_t plainText[] = { 116 0xe4, 0x2b, 0xcc, 0x08, 0x11, 0x79, 0x16, 0x1b, 0x35, 0x7f, 0xb3, 0xaf, 0x40, 0x3b, 0x3f, 0x7c 117 }; // Data to be verified, for reference only. 118 Crypto_DataBlob msgBlob = { 119 .data = reinterpret_cast<uint8_t *>(plainText), 120 .len = sizeof(plainText) 121 }; 122 123 uint8_t pubKeyText[] = { 124 0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 125 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x22, 0x00, 0x03, 0x4d, 0xe4, 0xbb, 0x11, 0x10, 126 0x1a, 0xd2, 0x05, 0x74, 0xf1, 0x0b, 0xb4, 0x75, 0x57, 0xf4, 0x3e, 0x55, 0x14, 0x17, 0x05, 0x4a, 127 0xb2, 0xfb, 0x8c, 0x84, 0x64, 0x38, 0x02, 0xa0, 0x2a, 0xa6, 0xf0 128 }; // Public key in DER format, for reference only. 129 130 Crypto_DataBlob keyBlob = { 131 .data = reinterpret_cast<uint8_t *>(pubKeyText), 132 .len = sizeof(pubKeyText) 133 }; 134 135 uint8_t signText[] = { 136 0x30, 0x44, 0x02, 0x20, 0x21, 0x89, 0x99, 0xb1, 0x56, 0x4e, 0x3a, 0x2c, 0x16, 0x08, 0xb5, 0x8a, 137 0x06, 0x6f, 0x67, 0x47, 0x1b, 0x04, 0x18, 0x7d, 0x53, 0x2d, 0xba, 0x00, 0x38, 0xd9, 0xe3, 0xe7, 138 0x8c, 0xcf, 0x76, 0x83, 0x02, 0x20, 0x13, 0x54, 0x84, 0x9d, 0x73, 0x40, 0xc3, 0x92, 0x66, 0xdc, 139 0x3e, 0xc9, 0xf1, 0x4c, 0x33, 0x84, 0x2a, 0x76, 0xaf, 0xc6, 0x61, 0x84, 0x5c, 0xae, 0x4b, 0x0d, 140 0x3c, 0xb0, 0xc8, 0x04, 0x89, 0x71 141 }; // Signature data, for reference only. 142 143 Crypto_DataBlob signBlob = { 144 .data = reinterpret_cast<uint8_t *>(signText), 145 .len = sizeof(signText) 146 }; 147 148 OH_Crypto_ErrCode ret = CRYPTO_SUCCESS; 149 150 ret = OH_CryptoAsymKeyGenerator_Create((const char *)"ECC256", &keyCtx); 151 if (ret != CRYPTO_SUCCESS) { 152 return false; 153 } 154 ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_DER, &keyBlob, nullptr, &keyPair); // Convert the public key in DER format to OH_CryptoKeyPair. 155 if (ret != CRYPTO_SUCCESS) { 156 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 157 return false; 158 } 159 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // Obtain the public key object. 160 // verify 161 ret = OH_CryptoVerify_Create((const char *)"ECC256|SHA256", &verify); // Create a Verify instance. 162 if (ret != CRYPTO_SUCCESS) { 163 OH_CryptoVerify_Destroy(verify); 164 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 165 return false; 166 } 167 ret = OH_CryptoVerify_Init(verify, pubKey); 168 if (ret != CRYPTO_SUCCESS) { 169 OH_CryptoVerify_Destroy(verify); 170 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 171 return false; 172 } 173 bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob); 174 if (res != true) { 175 OH_CryptoVerify_Destroy(verify); 176 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 177 return false; 178 } 179 180 OH_CryptoVerify_Destroy(verify); 181 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 182 OH_CryptoKeyPair_Destroy(keyPair); 183 return res; 184} 185``` 186