1# 使用RSA密钥对签名验签 (PKCS1模式)(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 10对应的算法规格请查看[签名验签算法规格:RSA](crypto-sign-sig-verify-overview.md#rsa)。 11 12## 在CMake脚本中链接相关动态库 13```txt 14target_link_libraries(entry PUBLIC libohcrypto.so) 15``` 16## 签名开发步骤 171. 调用[OH_CryptoSign_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_create),指定字符串参数'RSA1024|PKCS1|SHA256',创建Sign实例,用于完成签名操作。 18 192. 调用[OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init),使用私钥(OH_CryptoPrivKey)初始化Sign实例。 20 213. 调用[OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。如果数据量较小,可以直接调用OH_CryptoSign_Final接口一次性传入。 22 234. 调用[OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final),获取签名后的数据。 24 255. 调用[OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy)等释放内存。 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 }; // 待验证数据,仅供参考。 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## 验签开发步骤 97 981. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'RSA1024|PKCS1|SHA256',与签名的Sign实例保持一致。创建Verify实例,用于完成验签操作。 99 1002. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。 101 1023. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。 103 当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。 104 105 - 当待签名的数据较短时,可以在init完成后直接调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final)。 106 - 当数据量较大时,可以多次调用update,即[分段验签](crypto-rsa-sign-sig-verify-pkcs1-by-segment-ndk.md)。 107 1084. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。 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 }; // 待验证数据,仅供参考。 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 }; // 公钥DER编码数据,仅供参考。 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 }; // 签名数据,仅供参考。 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); // 创建非对称密钥生成器。 175 if (ret != CRYPTO_SUCCESS) { 176 return false; 177 } 178 ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair); // 将PEM格式的公钥编码数据转换为OH_CryptoKeyPair。 179 if (ret != CRYPTO_SUCCESS) { 180 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 181 return false; 182 } 183 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); // 获取公钥。 184 // verify 185 ret = OH_CryptoVerify_Create((const char *)"RSA1024|PKCS1|SHA256", &verify); // 创建Verify实例。 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); // 使用公钥初始化Verify实例。 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); // 对数据进行验签。 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