• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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