1# Converting SM2 Signature Formats (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 10HarmonyOS supports the conversion between the DER and R|S formats. 11You can specify SM2 ciphertext parameters and convert them to DER ciphertext. You can also extract SM2 ciphertext parameters from DER ciphertext. 12 13**Converting Ciphertext Parameters to DER Ciphertext** 141. Call [OH_CryptoEccSignatureSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_create) to create an [OH_CryptoEccSignatureSpec](../../reference/apis-crypto-architecture-kit/capi-cryptosignatureapi-oh-cryptoeccsignaturespec.md) object for setting SM2 ciphertext parameters. 15 162. Call [OH_CryptoEccSignatureSpec_SetRAndS](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_setrands) to set the **R** and **S** parameters in the **OH_CryptoEccSignatureSpec** object. 17 183. Call [OH_CryptoEccSignatureSpec_Encode](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_encode) to obtain the converted DER ciphertext. 19 204. Call [OH_CryptoEccSignatureSpec_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_destroy) to release the object. 21 22```c++ 23#include "CryptoArchitectureKit/crypto_common.h" 24#include "CryptoArchitectureKit/crypto_asym_key.h" 25#include "CryptoArchitectureKit/crypto_signature.h" 26 27static OH_Crypto_ErrCode doTestSm2DataChange() 28{ 29 static unsigned char g_rCoordinate[] = { 30 107, 93, 198, 247, 119, 18, 40, 110, 90, 156, 193, 31 158, 205, 113, 170, 128, 146, 109, 75, 17, 181, 109, 32 110, 91, 149, 5, 110, 233, 209, 78, 229, 96}; 33 34 static unsigned char g_sCoordinate[] = { 35 45, 153, 88, 82, 104, 221, 226, 43, 174, 21, 122, 36 248, 5, 232, 105, 41, 92, 95, 102, 224, 216, 149, 37 85, 236, 110, 6, 64, 188, 149, 70, 70, 183}; 38 39 // Generate DER signature data using R and S. 40 OH_CryptoEccSignatureSpec *spec = NULL; 41 Crypto_DataBlob r = {0}; 42 Crypto_DataBlob s = {0}; 43 r.data = g_rCoordinate; 44 r.len = sizeof(g_rCoordinate); 45 s.data = g_sCoordinate; 46 s.len = sizeof(g_sCoordinate); 47 OH_Crypto_ErrCode ret = OH_CryptoEccSignatureSpec_Create(NULL, &spec); 48 if (ret != CRYPTO_SUCCESS) { 49 OH_CryptoEccSignatureSpec_Destroy(spec); 50 return ret; 51 } 52 ret = OH_CryptoEccSignatureSpec_SetRAndS(spec, &r, &s); 53 if (ret != CRYPTO_SUCCESS) { 54 OH_CryptoEccSignatureSpec_Destroy(spec); 55 return ret; 56 } 57 Crypto_DataBlob sig = {0}; 58 ret = OH_CryptoEccSignatureSpec_Encode(spec, &sig); 59 if (ret != CRYPTO_SUCCESS) { 60 OH_CryptoEccSignatureSpec_Destroy(spec); 61 return ret; 62 } 63 OH_Crypto_FreeDataBlob(&sig); 64 OH_CryptoEccSignatureSpec_Destroy(spec); 65 spec = NULL; 66 return CRYPTO_SUCCESS; 67 68} 69``` 70 71**Converting DER Ciphertext to the R and S Parameters** 72 731. Call [OH_CryptoEccSignatureSpec_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_create) to pass the signature data and create a [OH_CryptoEccSignatureSpec](../../reference/apis-crypto-architecture-kit/capi-cryptosignatureapi-oh-cryptoeccsignaturespec.md) object to obtain the converted data. 74 752. Call [OH_CryptoEccSignatureSpec_GetRAndS](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_getrands) to obtain the converted **R** and **S** parameters. 76 773. Call [OH_CryptoEccSignatureSpec_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoeccsignaturespec_destroy) to free the memory. 78 79```c++ 80#include "CryptoArchitectureKit/crypto_common.h" 81#include "CryptoArchitectureKit/crypto_asym_key.h" 82#include "CryptoArchitectureKit/crypto_signature.h" 83 84static OH_Crypto_ErrCode doSm2GetRS() { 85 uint8_t signText[] = { 86 0x30, 0x45, 0x02, 0x21, 0x00, 0xab, 0xf8, 0xe2, 0x96, 0x7d, 0x5b, 0x28, 0xfb, 0x9a, 0xbd, 0x05, 0xa6, 87 0x81, 0xd6, 0xb1, 0x55, 0x69, 0x22, 0x25, 0xd2, 0xa3, 0x5d, 0xa8, 0xc0, 0x96, 0xe0, 0x1d, 0x38, 0x74, 88 0xa0, 0xc9, 0x4f, 0x02, 0x20, 0x20, 0x27, 0x04, 0x7a, 0x31, 0x94, 0xe7, 0x32, 0x61, 0xc3, 0x55, 0xa6, 89 0x5e, 0x1e, 0xdd, 0x3d, 0x04, 0x1c, 0x1e, 0x2d, 0x8d, 0x8d, 0x45, 0xca, 0xd9, 0x40, 0xe8, 0x97, 0xcd, 90 0x01, 0x18, 0xc5, 91 }; 92 Crypto_DataBlob signBlob = { 93 .data = reinterpret_cast<uint8_t *>(signText), 94 .len = sizeof(signText)}; 95 96 OH_CryptoEccSignatureSpec *eccSignSpec = nullptr; 97 OH_Crypto_ErrCode ret = OH_CryptoEccSignatureSpec_Create(&signBlob, &eccSignSpec); 98 if (ret != CRYPTO_SUCCESS) { 99 return ret; 100 } 101 102 Crypto_DataBlob r = {.data = nullptr, .len = 0}; 103 Crypto_DataBlob s = {.data = nullptr, .len = 0}; 104 ret = OH_CryptoEccSignatureSpec_GetRAndS(eccSignSpec, &r, &s); 105 if (ret != CRYPTO_SUCCESS) { 106 OH_CryptoEccSignatureSpec_Destroy(eccSignSpec); 107 return ret; 108 } 109 OH_Crypto_FreeDataBlob(&r); 110 OH_Crypto_FreeDataBlob(&s); 111 OH_CryptoEccSignatureSpec_Destroy(eccSignSpec); 112 return CRYPTO_SUCCESS; 113} 114``` 115