Cryptography API: Next Generation(CNG)使用梳理——非对称加密算法应用(三)与OpenSSL3之间的非对称密钥转换(ECC)

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

此篇整理了一下OpenSSL3.0+和CNG之间密钥的相互转换

 ECC部分:

CNG导出密钥的内存BLOB结构为:BCRYPT_ECCPRIVATE_BLOBBCRYPT_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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值