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

本文详细介绍了RSA密钥在MicrosoftCNG(CryptoAPINextGeneration)与OpenSSL之间的转换过程,包括公钥和私钥的结构、转换方法以及涉及到的数学计算。转换过程中特别提到了大端到本机字节序的转换和不同系统版本下私钥指数的计算差异。

继续之前章节的内容,这里说一下RSA

RSA部分:

BCrypt导出密钥的内存BLOB结构有三种:BCRYPT_RSAFULLPRIVATE_BLOB、BCRYPT_RSAPRIVATE_BLOB和BCRYPT_RSAPUBLIC_BLOB

简单理解为BCRYPT_RSAFULLPRIVATE_BLOB同时包含公钥和私钥

即RSA的:

e = 公钥指数
d = 私钥指数
n = 模数
p = 质因子
q = 质因子
dmp1 = d mod (p-1)
dmq1 = d mod (q-1)
iqmp = q^-1 mod p

其中,公钥指数e一般为0x3L或者0x10001L(65537),CNG和OpenSSL一般使用65537

不论是BCRYPT_RSAFULLPRIVATE_BLOB、BCRYPT_RSAPRIVATE_BLOB还是BCRYPT_RSAPUBLIC_BLOB都包含一个BCRYPT_RSAKEY_BLOB结构的文件头

typedef struct _BCRYPT_RSAKEY_BLOB {
  ULONG Magic;
  ULONG BitLength;
  ULONG cbPublicExp;
  ULONG cbModulus;
  ULONG cbPrime1;
  ULONG cbPrime2;
} BCRYPT_RSAKEY_BLOB;

Magic 指定此 BLOB 表示的 RSA 密钥的类型。 这可以是以下值之一。

        BCRYPT_RSAPUBLIC_MAGIC 密钥是 RSA 公钥。

        BCRYPT_RSAPRIVATE_MAGIC 密钥是 RSA 私钥。

        BCRYPT_RSAFULLPRIVATE_MAGIC 密钥是完整的 RSA 私钥。

BitLength 密钥的大小(以位为单位)。

cbPublicExp 键指数(e)的大小(以字节为单位)。 截至 1903 Windows 10 版本,不再支持大于 (2^64 - 1) 的公共指数。

cbModulus 键的模数(n)的大小(以字节为单位)。

cbPrime1 键的第一个质数(p)的大小(以字节为单位)。 这仅用于私钥 BLOB。

cbPrime2 键的第二个质数(q)的大小(以字节为单位)。 这仅用于私钥 BLOB。

RSA 公钥 BLOB(BCRYPT_RSAPUBLIC_BLOB )在连续内存中采用以下格式。 结构后面的所有数字都采用大端格式。

BCRYPT_RSAKEY_BLOB
PublicExponent[cbPublicExp] // Big-endian.
Modulus[cbModulus] // Big-endian.

RSA 私钥 BLOB (BCRYPT_RSAPRIVATE_BLOB) 在连续内存中采用以下格式。 结构后面的所有数字都采用大端格式。

BCRYPT_RSAKEY_BLOB
PublicExponent[cbPublicExp] // Big-endian.
Modulus[cbModulus] // Big-endian.
Prime1[cbPrime1] // Big-endian.
Prime2[cbPrime2] // Big-endian.

完整的 RSA 私钥 BLOB (BCRYPT_RSAFULLPRIVATE_BLOB) 在连续内存中采用以下格式。 结构后面的所有数字都采用大端格式。

BCRYPT_RSAKEY_BLOB
PublicExponent[cbPublicExp] // Big-endian.-- e
Modulus[cbModulus] // Big-endian.-- n
Prime1[cbPrime1] // Big-endian.-- p
Prime2[cbPrime2] // Big-endian.-- q
Exponent1[cbPrime1] // Big-endian.-- d mod (p-1)
Exponent2[cbPrime2] // Big-endian.-- d mod (q-1)
Coefficient[cbPrime1] // Big-endian.-- (inverse of q) mod p //q模p的乘法逆元即qInv *q = 1 (mod p)
PrivateExponent[cbModulus] // Big-endian.-- d

MSDN中明确说明PrivateExponent根据不同系统版本等效数学模型,其计算公式是不同的可能是modulo (Prime1 - 1) * (Prime2 - 1) ,或者 modulo LeastCommonMultiple (Prime1 - 1, Prime2 - 1),额外说一句两个公式的计算结果所得的PrivateExponent可能相同,也可能不同,如果两种不同的话,后者modulo LeastCommonMultiple (Prime1 - 1, Prime2 - 1)的结果会比前者modulo (Prime1 - 1) * (Prime2 - 1) 的结果来的小(位数),相对使用时,速度会更快一些

OpenSSL中关于RSA的定义(仅供参考,OpenSSL后续版本内部实现可能会有变化)

typedef struct rsa_st {
    // RSA 公钥部分
    BIGNUM *n;    // 模数 (modulus)
    BIGNUM *e;    // 公共指数 (public exponent)
 
    // RSA 私钥部分
    BIGNUM *d;    // 私有指数 (private exponent)
    BIGNUM *p;    // 第一个大素数 (prime1)
    BIGNUM *q;    // 第二个大素数 (prime2)
 
    // 预计算值,用于加快密钥运算速度
    BIGNUM *dmp1; // d 对 (p-1) 求模 (d mod (p-1))
    BIGNUM *dmq1; // d 对 (q-1) 求模 (d mod (q-1))
    BIGNUM *iqmp; // q 对 p 的模反元素 (q^(-1) mod p)
 
    // 私有成员 (不建议直接访问)
    CRYPTO_EX_DATA ex_da
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值