C++使用OpenSSL库中的ECDSA签名验签
//此代码不支持openssl3.0 以上版本
//生成ECDSA密钥对
void _generateKeys(EC_KEY *&eckey);
{
bool success(true);
eckey = EC_KEY_new();
if (!eckey)
{
std::cout << "Failed to create new EC Key..." << std::endl;
success = false;
}
/* 设置spec256k1的曲线group */
EC_GROUP* ecgroup = EC_GROUP_new_by_curve_name(EC_CURVE);
//auto ecgroup_temp = make_handle(ecgroup, EC_GROUP_free);
if (!ecgroup)
{
std::cout << "Failed to create new EC Group..." << std::endl;
success = false;
}
/* 设置key的group属性 */
if (EC_KEY_set_group(eckey, ecgroup)==0)
{
std::cout << "Failed to set group for EC Key..." << std::endl;
success = false;
}
//generate ECC key
if (EC_KEY_generate_key(eckey)==0)
{
std::cout << "Failed to generate EC Key..." << std::endl;
success = false;
}
EC_GROUP_free(ecgroup);
if (!success)
{
EC_KEY_free(eckey);
std::cout << " create ec key failed " <<std::endl;
return;
}
}
//使用ECDSA私钥来签名
bool ecdsaSign(const std::string& hash, EC_KEY * eckey, std::string &signMessage)
{
std::vector<unsigned char> vchSig;
// Get EC Key from keyHandle
if (!eckey) return false;
// Sigh hash using EC Key from keyHandle
ECDSA_SIG* signature = ECDSA_do_sign((const unsigned char*)hash.c_str(), (int)hash.size(), eckey);
//auto signature_temp = make_handle(signature, ECDSA_SIG_free);
if (!signature)
{
std::cout << "Failed to generate EC Signature..." << std::endl;
ECDSA_SIG_free(signature);
return false;
}
unsigned int nSize = ECDSA_size(eckey);
vchSig.resize(nSize);
unsigned char *pos = &vchSig[0];
nSize = i2d_ECDSA_SIG(signature, &pos);
vchSig.resize(nSize);
for(int i = 0; i < vchSig.size(); ++i)
{
signMessage += vchSig[i];
}
ECDSA_SIG_free(signature);
return true;
}
//使用ECDSA公钥验签
bool ecdsaVerify(const std::string& hash, const std::string &signMessage, EC_KEY * eckey)
{
std::vector<unsigned char> vchSig;
for(int i = 0; i < signMessage.size(); ++i)
{
vchSig.push_back(signMessage[i]);
}
if (vchSig.empty()) return false;
unsigned char *norm_der = NULL;
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
const unsigned char* sigptr = &vchSig[0];
assert(norm_sig);
if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
{
ECDSA_SIG_free(norm_sig);
return false;
}
int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
if (derlen <= 0) return false;
// Verify Signature
if (ECDSA_do_verify((const unsigned char*)hash.c_str(), (int)hash.size(), norm_sig, eckey) != 1)
{
std::cout << "Failed to verify EC Signature..." << std::endl;
return false;
}
ECDSA_SIG_free(norm_sig);
return true;
}
//测试
int main(int argc, char ** argv)
{
EC_KEY* eckey = nullptr;
_generateKeys(eckey);
if(eckey == nullptr)
{
std::cout << "generate key fail" << std::endl;
return -1;
}
std::string message = "ABC";
std::string signature;
if(ecdsaSign(message, eckey, signature) == false)
{
std::cout << "sign fail" << std::endl;
return -1;
}
if(ecdsaVerify(message, signature, eckey) == false)
{
std::cout << "verify fail" << std::endl;
return -2;
}
std::cout << "success !" << std::endl;
return 0;
return 0;
}