此篇整理了一下OpenSSL3.0+和CNG之间密钥的相互转换
ECC部分:
CNG导出密钥的内存BLOB结构为:BCRYPT_ECCPRIVATE_BLOB和BCRYPT_ECCPUBLIC_BLOB
椭圆曲线(ECC) 公钥 BLOB (BCRYPT_ECCPUBLIC_BLOB) 在连续内存中具有以下格式。 X 和 Y 坐标是以大端格式编码的无符号整数。
BCRYPT_ECCKEY_BLOB
BYTE X[cbKey] // Big-endian.
BYTE Y[cbKey] // Big-endian.
OpenSSL中ECC公钥为点格式,可以用EC_POINT_set_affine_coordinates函数转换一下即可
椭圆曲线(ECC) 私钥 BLOB (BCRYPT_ECCPRIVATE_BLOB) 在连续内存中具有以下格式。 X 和 Y 坐标和 d 值是以大端格式编码的无符号整数。
BCRYPT_ECCKEY_BLOB
BYTE X[cbKey] // Big-endian.
BYTE Y[cbKey] // Big-endian.
BYTE d[cbKey] // Big-endian.
而在讲OpenSSL3关于ECC密钥的结构前,很遗憾的说OpenSSL3开始已经放弃了对EC_KEY结构的直接构造和读写,转而需要通过对EVP_PKEY抽象的读写和构造,所以整个转换过程有点繁琐和抽象
为了方便转换定义了 一些辅助函数
//判断导出的BLOB是否为EC公钥
bool Is_CNG_EC_Public_Key(PBCRYPT_ECCKEY_BLOB pubKey)
{
switch(pubKey->dwMagic) {
case BCRYPT_ECDH_PUBLIC_P256_MAGIC:
case BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
case BCRYPT_ECDH_PUBLIC_P384_MAGIC:
case BCRYPT_ECDSA_PUBLIC_P384_MAGIC:
case BCRYPT_ECDH_PUBLIC_P521_MAGIC:
case BCRYPT_ECDSA_PUBLIC_P521_MAGIC:
return true;
}
return false;
}
//判断导出的BLOB是否为EC私钥
bool Is_CNG_EC_Private_Key(PBCRYPT_ECCKEY_BLOB pvtKey)
{
switch(pvtKey->dwMagic) {
case BCRYPT_ECDH_PRIVATE_P256_MAGIC:
case BCRYPT_ECDSA_PRIVATE_P256_MAGIC:
case BCRYPT_ECDH_PRIVATE_P384_MAGIC:
case BCRYPT_ECDSA_PRIVATE_P384_MAGIC:
case BCRYPT_ECDH_PRIVATE_P521_MAGIC:
case BCRYPT_ECDSA_PRIVATE_P521_MAGIC:
return true;
}
return false;
}
//将OpenSSL的nid转换为ECCKEY_BLOB中的Magic
int ECDH_NID_to_CNG_Magic(int nid, bool isPrivate)
{
if (isPrivate) {
switch(nid) {
case NID_X9_62_prime256v1:
return BCRYPT_ECDH_PRIVATE_P256_MAGIC;
case NID_secp384r1:
return BCRYPT_ECDH_PRIVATE_P384_MAGIC;
case NID_secp521r1:
return BCRYPT_ECDH_PRIVATE_P521_MAGIC;
}
}
else {
switch(nid) {
case NID_X9_62_prime256v1:
return BCRYPT_ECDH_PUBLIC_P256_MAGIC;
case NID_secp384r1:
return BCRYPT_ECDH_PUBLIC_P384_MAGIC;
case NID_secp521r1:
return BCRYPT_ECDH_PUBLIC_P521_MAGIC;
}
}
return 0;
}
//同上
int ECDSA_NID_to_CNG_Magic(int nid, bool isPrivate)
{
if (isPrivate) {
switch(nid) {
case NID_X9_62_prime256v1:
return BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
case NID_secp384r1:
return BCRYPT_ECDSA_PRIVATE_P384_MAGIC;
case NID_secp521r1:
return BCRYPT_ECDSA_PRIVATE_P521_MAGIC;
}
}
else {
switch(nid) {
case NID_X9_62_prime256v1:
return BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
case NID_secp384r1:
return BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
case NID_secp521r1:
return BCRYPT_ECDSA_PUBLIC_P521_MAGIC;
}
}
return 0;
}
//将ECCKEY_BLOB中的Magic转换为OpenSSL的nid
int CNG_Magic_to_NID (int magic)
{
switch(magic) {
case BCRYPT_ECDH_PRIVATE_P256_MAGIC:
case BCRYPT_ECDSA_PRIVATE_P256_MAGIC:
case BCRYPT_ECDH_PUBLIC_P256_MAGIC:
case BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
return NID_X9_62_prime256v1;
case BCRYPT_ECDH_PRIVATE_P384_M

本文详细介绍了如何在OpenSSL3.0和CNG之间进行ECC(椭圆曲线加密)密钥的相互转换,涉及到BCRYPT_ECCKEY_BLOB结构以及EVP_PKEY抽象的使用,包括公钥和私钥的转换方法,以及相关的辅助函数实现。
最低0.47元/天 解锁文章
3125

被折叠的 条评论
为什么被折叠?



