将ECDSA Keypair的公共和私钥分开
Separating public and private keys of ECDSA keypair
我正在使用C 尝试从OpenSSL Wiki中生成Elliptic_curve_cryptography之后的ECDSA密钥对。
#include <iostream>
#include <openssl/obj_mac.h>
#include <openssl/ec.h>
int main()
{
EC_KEY *key;
if(NULL == (key = EC_KEY_new_by_curve_name(NID_secp224r1)))
std::cout << "error on new_curve_by_name" << std::endl;
if(1 != EC_KEY_generate_key(key)) std::cout << "error in generating keys" << std::endl;
}
键对生成没有错误的生成,但我不知道如何在两个不同的对象(EC_Point和bignum(中提取公共和私钥,任何想法?
我认为您想要的方法是:
ec_key_get0_private_key和ec_key_get0_public_key
这对我有用:
EC_KEY* key = EC_KEY_new_by_curve_name(NID_secp224r1);
if(!key)
{
std::cerr << "Error creating curve key" << 'n';
return EXIT_FAILURE;
}
if(!EC_KEY_generate_key(key))
{
std::cerr << "Error generating curve key" << 'n';
EC_KEY_free(key);
return EXIT_FAILURE;
}
BIGNUM const* prv = EC_KEY_get0_private_key(key);
if(!prv)
{
std::cerr << "Error getting private key" << 'n';
EC_KEY_free(key);
return EXIT_FAILURE;
}
std::cout << "Private key: " << prv << 'n';
EC_POINT const* pub = EC_KEY_get0_public_key(key);
if(!pub)
{
std::cerr << "Error getting public key" << 'n';
EC_KEY_free(key);
return EXIT_FAILURE;
}
std::cout << "Public key: " << pub << 'n';
// Use keys here ...
EC_KEY_free(key);
注意:
当使用这样的C
库时,我经常定义一个自定义智能指针,以确保是否删除。这使得代码不容易泄漏内存和"异常安全"。
例如,我将定义这样的内容:
struct ec_key_dter{void operator()(EC_KEY* k)const{if(k) EC_KEY_free(k);}};
using ec_key_uptr = std::unique_ptr<EC_KEY, ec_key_dter>;
并这样使用:
auto key = ec_key_uptr(EC_KEY_new_by_curve_name(NID_secp224r1));
if(!key)
throw std::runtime_error("Error creating curve key");
if(!EC_KEY_generate_key(key.get()))
throw std::runtime_error("Error generating curve key");
if(!EC_KEY_check_key(key.get()))
throw std::runtime_error("Error checking curve key");
// ... etc ...
// Do not delete the key manually!!
我认为您必须执行以下操作:
BIGNUM *privateKey;
EC_POINT *publicKey;
privateKey = BN_new();
EC_KEY_set_private_key(key, privateKey);
EC_KEY_set_public_key(key, publicKey);
编辑:
这两个呼叫将分别设置privateKey
和publicKey
。Open SSL文档声称" 目标应是通过调用 BN_new()
的呼叫获得的新分配的bignum。它不应以其他方式使用或以任何方式使用。。",因此我正在添加BN_new()
调用。
我看不到任何类似的创建ec_point对象的东西(除非您使用ec_group来创建这种方式: EC_POINT *EC_POINT_new(const EC_GROUP *group);
所以尝试一下,如果您仍然不明白,那么也许您应该研究如何根据您的用法正确创建ec_point对象。
这将私钥返回为bignum
BIGNUM* bn = EC_KEY_get0_private_key(key);
对于公共密钥,不确定如何获得ec_point,但是您可以使用以下内容获得原始字节:
// first call returns length of key
int len = i2o_ECPublicKey(key, 0);
std::vector<unsigned char> bytes b(len, 0);
unsigned char* p = &b[0];
// second call copies key into p (and returns length if successful)
if (i2o_ECPublicKey(key, &p)) != len)
{
// handle error
}
相关文章:
- 如何在openssl-ecc中获取十六进制格式的私钥
- 如何在C++中使用X509证书模在令牌中查找私钥
- 私钥解密代码使用公共接口说明符到 BSAFE 库 v6.0?
- 从字符串 Crypto++ 导入 RSA 公钥/私钥
- 将私钥和证书存储在C++/OpenSSL中
- 区块链超级账本私钥错误
- 博坦加载现有的 RSA 私钥
- C 从XML导入CAPI/CNG中的RSA私钥
- 使用密码将 RSA 私钥写入 PEM 文件
- 一代 RSA-2048 密钥(公钥和私钥)
- 如何获取PCCERT_CONTEXT私钥的NCRYPT_KEY_HANDLE?
- 将ECDSA Keypair的公共和私钥分开
- RSA 私钥加密 QT C++
- 在 SSH 上的公钥-私钥身份验证上的 libcurl 实现
- 使用 openssl libcrypto 解密具有 RSA 私钥的数据时RSA_NO_PADDING的使用
- 使用 WinInet 的客户端身份验证(证书 + 私钥)
- OpenSSL AES_CFB128_ENCRYPT公共/私钥C
- 如何通过PKCS#11 API从电子令牌获取私钥
- 使用 OpenSSL 生成私钥
- 创建给定曲线和私有指数的ECDSA私钥