1# 使用RSA密钥对签名验签 (PSS模式)(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),指定字符串参数'RSA2048|PSS|SHA256|MGF1_SHA256',创建非对称密钥类型为RSA2048、填充模式为PSS、摘要算法为SHA256、掩码算法为MGF1_SHA256的Sign实例,用于完成签名操作。 182. 调用[OH_CryptoSign_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_init),使用私钥(OH_CryptoPrivKey)初始化Sign实例。 193. 调用[OH_CryptoSign_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_update),传入待签名的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。如果数据量较小,可以直接调用OH_CryptoSign_Final接口一次性传入。 204. 调用[OH_CryptoSign_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_final),获取签名后的数据。 215. 调用[OH_CryptoSign_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptosign_destroy)等释放内存。 22 23```c++ 24#include "CryptoArchitectureKit/crypto_common.h" 25#include "CryptoArchitectureKit/crypto_signature.h" 26#include "CryptoArchitectureKit/crypto_asym_key.h" 27 28static OH_Crypto_ErrCode doTestRsaPssSignSeg() { 29 OH_CryptoAsymKeyGenerator *keyCtx = nullptr; 30 OH_CryptoKeyPair *keyPair = nullptr; 31 OH_CryptoSign *sign = nullptr; 32 Crypto_DataBlob signData = {.data = nullptr, .len = 0}; 33 34 uint8_t plainText[] = { 35 0x13, 0xa7, 0x73, 0xe8, 0xb8, 0x22, 0x99, 0x72, 0x98, 0x29, 0xae, 0x74, 0xa8, 0x4a, 0xea, 0xa9, 36 }; 37 Crypto_DataBlob msgBlob = { 38 .data = reinterpret_cast<uint8_t *>(plainText), 39 .len = sizeof(plainText) 40 }; 41 42 OH_Crypto_ErrCode ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx); 43 if (ret != CRYPTO_SUCCESS) { 44 return ret; 45 } 46 ret = OH_CryptoAsymKeyGenerator_Generate(keyCtx, &keyPair); 47 if (ret != CRYPTO_SUCCESS) { 48 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 49 return ret; 50 } 51 52 OH_CryptoPrivKey *privKey = OH_CryptoKeyPair_GetPrivKey(keyPair); 53 ret = OH_CryptoSign_Create((const char *)"RSA2048|PSS|SHA256|MGF1_SHA256", &sign); 54 if (ret != CRYPTO_SUCCESS) { 55 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 56 OH_CryptoKeyPair_Destroy(keyPair); 57 return ret; 58 } 59 60 ret = OH_CryptoSign_Init(sign, privKey); 61 if (ret != CRYPTO_SUCCESS) { 62 OH_CryptoSign_Destroy(sign); 63 OH_CryptoKeyPair_Destroy(keyPair); 64 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 65 return ret; 66 } 67 ret = OH_CryptoSign_Update(sign, &msgBlob); 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_Final(sign, nullptr, &signData); 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 82 OH_CryptoSign_Destroy(sign); 83 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 84 OH_CryptoKeyPair_Destroy(keyPair); 85 return CRYPTO_SUCCESS; 86} 87 88``` 89 90## 开发步骤 91 921. 调用[OH_CryptoVerify_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_create),指定字符串参数'RSA2048|PSS|SHA256|MGF1_SHA256',创建非对称密钥类型为RSA2048、填充模式为PSS、摘要算法为SHA256、掩码算法为MGF1_SHA256的Verify实例,用于完成验签操作。 93 942. 调用[OH_CryptoVerify_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_setparam),设置签名参数。需要与签名时设置的保持一致。 95 963. 调用[OH_CryptoVerify_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_init),使用公钥(OH_CryptoPubKey)初始化Verify实例。 97 984. 调用[OH_CryptoVerify_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_update),传入待验证的数据。当前单次update长度没有限制,开发者可以根据数据量判断如何调用update,如果数据量较小,可以直接调用OH_CryptoVerify_Final接口一次性传入。 99 1005. 调用[OH_CryptoVerify_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-signature-h.md#oh_cryptoverify_final),对数据进行验签。 101 102```c++ 103#include "CryptoArchitectureKit/crypto_common.h" 104#include "CryptoArchitectureKit/crypto_signature.h" 105#include "CryptoArchitectureKit/crypto_asym_key.h" 106 107static bool doTestRsaPssSignatureSeg() 108{ 109 OH_CryptoAsymKeyGenerator *keyCtx = nullptr; 110 OH_CryptoKeyPair *keyPair = nullptr; 111 OH_CryptoVerify *verify = nullptr; 112 113 uint8_t plainText[] = { 114 0x13, 0xa7, 0x73, 0xe8, 0xb8, 0x22, 0x99, 0x72, 0x98, 0x29, 0xae, 0x74, 0xa8, 0x4a, 0xea, 0xa9, 115 }; 116 Crypto_DataBlob msgBlob = { 117 .data = reinterpret_cast<uint8_t *>(plainText), 118 .len = sizeof(plainText) 119 }; 120 121 uint8_t pubKeyText[] = { 122 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 123 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 124 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x76, 0x6a, 0x6c, 0x59, 0x35, 125 0x53, 0x72, 0x54, 0x57, 0x32, 0x43, 0x78, 0x74, 0x47, 0x32, 0x54, 0x67, 0x54, 0x54, 0x39, 0x39, 126 0x78, 0x71, 0x37, 0x62, 0x4e, 0x41, 0x6b, 0x54, 0x2b, 0x65, 0x6a, 0x75, 0x65, 0x7a, 0x37, 0x39, 127 0x37, 0x2f, 0x65, 0x63, 0x56, 0x4b, 0x34, 0x78, 0x37, 0x58, 0x41, 0x4d, 0x6d, 0x73, 0x4a, 0x0a, 128 0x4a, 0x63, 0x66, 0x49, 0x36, 0x73, 0x54, 0x4d, 0x4e, 0x68, 0x45, 0x6b, 0x70, 0x79, 0x63, 0x31, 129 0x4b, 0x32, 0x46, 0x6e, 0x30, 0x74, 0x59, 0x47, 0x2f, 0x6d, 0x4d, 0x37, 0x72, 0x71, 0x6d, 0x6a, 130 0x6c, 0x6b, 0x75, 0x72, 0x34, 0x72, 0x74, 0x6a, 0x4a, 0x4a, 0x75, 0x66, 0x34, 0x35, 0x45, 0x42, 131 0x30, 0x79, 0x6c, 0x55, 0x65, 0x47, 0x61, 0x39, 0x6d, 0x44, 0x4a, 0x57, 0x76, 0x62, 0x2b, 0x73, 132 0x0a, 0x41, 0x4a, 0x78, 0x33, 0x41, 0x44, 0x78, 0x70, 0x50, 0x31, 0x59, 0x36, 0x46, 0x61, 0x71, 133 0x54, 0x44, 0x6e, 0x64, 0x47, 0x41, 0x6e, 0x6b, 0x65, 0x4d, 0x53, 0x2f, 0x56, 0x71, 0x53, 0x45, 134 0x65, 0x75, 0x43, 0x36, 0x4d, 0x42, 0x38, 0x52, 0x53, 0x65, 0x6f, 0x31, 0x4f, 0x59, 0x4c, 0x53, 135 0x73, 0x7a, 0x36, 0x43, 0x76, 0x38, 0x34, 0x76, 0x76, 0x53, 0x69, 0x32, 0x37, 0x32, 0x51, 0x44, 136 0x6e, 0x0a, 0x6f, 0x4b, 0x4f, 0x4d, 0x34, 0x43, 0x78, 0x6d, 0x6e, 0x32, 0x31, 0x58, 0x5a, 0x43, 137 0x5a, 0x2f, 0x59, 0x50, 0x32, 0x35, 0x67, 0x5a, 0x6e, 0x57, 0x4f, 0x61, 0x42, 0x4c, 0x50, 0x57, 138 0x79, 0x6f, 0x48, 0x46, 0x65, 0x49, 0x55, 0x42, 0x48, 0x4c, 0x50, 0x69, 0x4a, 0x2b, 0x72, 0x58, 139 0x48, 0x4e, 0x65, 0x4f, 0x38, 0x2b, 0x70, 0x6c, 0x37, 0x49, 0x42, 0x74, 0x66, 0x35, 0x67, 0x70, 140 0x4a, 0x76, 0x0a, 0x31, 0x6e, 0x78, 0x72, 0x45, 0x4b, 0x73, 0x75, 0x2b, 0x6e, 0x64, 0x48, 0x43, 141 0x6e, 0x46, 0x64, 0x6f, 0x38, 0x2f, 0x49, 0x46, 0x46, 0x4a, 0x6a, 0x70, 0x36, 0x73, 0x6f, 0x55, 142 0x4a, 0x4f, 0x5a, 0x52, 0x4b, 0x6e, 0x6f, 0x41, 0x4b, 0x34, 0x67, 0x6a, 0x34, 0x48, 0x30, 0x50, 143 0x76, 0x49, 0x79, 0x4d, 0x67, 0x4b, 0x61, 0x43, 0x43, 0x41, 0x55, 0x57, 0x70, 0x4a, 0x65, 0x76, 144 0x35, 0x42, 0x52, 0x0a, 0x42, 0x4f, 0x56, 0x38, 0x4f, 0x59, 0x34, 0x48, 0x48, 0x6f, 0x42, 0x6b, 145 0x47, 0x4d, 0x6e, 0x32, 0x71, 0x6a, 0x4d, 0x48, 0x78, 0x49, 0x6c, 0x71, 0x48, 0x50, 0x67, 0x59, 146 0x70, 0x41, 0x53, 0x50, 0x51, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0a, 0x2d, 0x2d, 0x2d, 147 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 148 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 149 }; 150 151 Crypto_DataBlob keyBlob = { 152 .data = reinterpret_cast<uint8_t *>(pubKeyText), 153 .len = sizeof(pubKeyText) 154 }; 155 156 uint8_t signText[] = { 157 0xac, 0x2b, 0x12, 0x56, 0x1c, 0xe1, 0x60, 0x49, 0xc2, 0xd9, 0x87, 0x89, 0xfb, 0xa3, 0xc5, 0x41, 158 0x64, 0x7f, 0x6f, 0x80, 0xc8, 0xdb, 0xb3, 0xdf, 0x25, 0x76, 0x4b, 0x1e, 0x51, 0xaa, 0x0a, 0x6d, 159 0x83, 0x49, 0xae, 0x00, 0x7a, 0x99, 0xf4, 0xc8, 0x98, 0x45, 0x71, 0xfc, 0x5e, 0xdb, 0xed, 0x31, 160 0xad, 0xf2, 0x35, 0x05, 0xe2, 0x3e, 0xf1, 0xcb, 0x96, 0xb2, 0xb9, 0x59, 0xaf, 0x30, 0x25, 0xb0, 161 0xda, 0x83, 0x18, 0x2b, 0x11, 0xa4, 0x93, 0x2d, 0x9e, 0x93, 0x99, 0x62, 0xdd, 0xea, 0x1b, 0xfa, 162 0x60, 0xb8, 0xea, 0x9c, 0xef, 0x4f, 0x2b, 0x9d, 0xd1, 0x3e, 0xe1, 0x6b, 0x24, 0x98, 0x9d, 0x32, 163 0xa3, 0x1e, 0x9d, 0x45, 0xe7, 0x3d, 0x51, 0x7e, 0x3b, 0x0c, 0xee, 0x3f, 0xca, 0x29, 0xd9, 0x02, 164 0xe5, 0xb8, 0xf5, 0x89, 0x06, 0xf4, 0xfe, 0x27, 0x44, 0xff, 0x38, 0xed, 0x5a, 0x0e, 0x89, 0x16, 165 0x15, 0x26, 0xf0, 0xb2, 0x4c, 0x95, 0xee, 0x0a, 0xd3, 0x61, 0xc7, 0xb2, 0x4b, 0xfd, 0x20, 0xb9, 166 0x83, 0x25, 0x43, 0x4d, 0xa0, 0x3d, 0xaa, 0x40, 0x7b, 0xac, 0x01, 0x48, 0x8e, 0x2a, 0x96, 0x11, 167 0xc0, 0x31, 0x51, 0x5b, 0xaf, 0xeb, 0x8b, 0xaf, 0xb5, 0x88, 0xcb, 0xe0, 0x97, 0x45, 0x36, 0xe9, 168 0x6e, 0x6e, 0xe0, 0x55, 0xea, 0xf4, 0xd2, 0x88, 0xbb, 0xc9, 0x85, 0x94, 0xd5, 0x65, 0xeb, 0xa3, 169 0x1c, 0xd1, 0xd6, 0xf5, 0x22, 0x29, 0xf1, 0x16, 0xa5, 0x53, 0x1b, 0xd0, 0x6c, 0xf6, 0x0d, 0xa8, 170 0xd4, 0xe4, 0xb2, 0x0a, 0x92, 0x64, 0x7a, 0x6d, 0xf2, 0x76, 0xf3, 0xb0, 0x08, 0x44, 0x31, 0x31, 171 0x90, 0x48, 0x9e, 0x2e, 0x03, 0xc7, 0xab, 0x5d, 0x7a, 0x07, 0x1f, 0x1d, 0x10, 0x21, 0x54, 0x60, 172 0x0d, 0x26, 0xe4, 0x1c, 0xc7, 0x82, 0x03, 0x65, 0x64, 0x70, 0x41, 0x68, 0x0f, 0xfa, 0x64, 0x3c, 173 }; 174 175 Crypto_DataBlob signBlob = { 176 .data = reinterpret_cast<uint8_t *>(signText), 177 .len = sizeof(signText) 178 }; 179 180 OH_Crypto_ErrCode ret = CRYPTO_SUCCESS; 181 ret = OH_CryptoAsymKeyGenerator_Create((const char *)"RSA2048", &keyCtx); 182 if (ret != CRYPTO_SUCCESS) { 183 return false; 184 } 185 ret = OH_CryptoAsymKeyGenerator_Convert(keyCtx, CRYPTO_PEM, &keyBlob, nullptr, &keyPair); 186 if (ret != CRYPTO_SUCCESS) { 187 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 188 return false; 189 } 190 OH_CryptoPubKey *pubKey = OH_CryptoKeyPair_GetPubKey(keyPair); 191 192 ret = OH_CryptoVerify_Create((const char *)"RSA2048|PSS|SHA256|MGF1_SHA256", &verify); 193 if (ret != CRYPTO_SUCCESS) { 194 OH_CryptoVerify_Destroy(verify); 195 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 196 return false; 197 } 198 ret = OH_CryptoVerify_Init(verify, pubKey); 199 if (ret != CRYPTO_SUCCESS) { 200 OH_CryptoVerify_Destroy(verify); 201 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 202 return false; 203 } 204 bool res = OH_CryptoVerify_Final(verify, &msgBlob, &signBlob); 205 if (res != true) { 206 OH_CryptoVerify_Destroy(verify); 207 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 208 return false; 209 } 210 211 OH_CryptoVerify_Destroy(verify); 212 OH_CryptoAsymKeyGenerator_Destroy(keyCtx); 213 OH_CryptoKeyPair_Destroy(keyPair); 214 return res; 215} 216``` 217