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_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## 验签开发步骤 109 1101. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'RSA1024|PKCS1|SHA256',与签名的Sign实例保持一致。创建Verify实例,用于完成验签操作。 111 1122. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。 113 1143. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。 115 1164. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。 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