RSA的算法,最好的文章是: somenzz:一文搞懂 RSA 算法
文章直接举例,让人很容易理解 RSA 中的 p, q, n, m, e, d 的关系。
一个关键点就是 (n, e)组成公钥, (n, d)组成私钥。 公私钥并不是一个独立的大数。而是一个二元组。
到了 openssl ,私钥表达为:
![a0ef3b7bed5409eb4285fb445a625ab8.png](https://i-blog.csdnimg.cn/blog_migrate/3de1543b126b7d90fb4a99c7c5a01e4d.jpeg)
如果使用下面的命令:
openssl rsa -in private.pem -text -noout | less
就可以把一个私钥文件展开成上面的结构体中的每个分量。
私钥不应该只包含(n,d)对吗?为什么有6个额外的组件?它包含e(public exponent),这样就可以从private.pem private rsa密钥生成/提取/派生public rsa密钥。剩下的5个组件用于加速解密过程。结果表明,通过预计算和存储这5个值,可以将RSA解密速度提高4倍。解密不需要这5个组件就可以工作,但是如果您方便的话,可以更快地完成。加速算法基于中国余数定理。所以,private.pem rsa private key实际上包含了这8个值中的所有值;
使用命令
openssl rsa -in private.pem -out public.pem -pubout
可以提取出公钥。私钥文件保存的信息可以解出公钥。
再使用命令
openssl rsa -in public.pem -text -pubin -noout
就可以看到两个分量:
Modulus - n
Exponent (public) - e
这就是开始提到的 (n, e) 是公钥。
注:pkcs 1 v2.0标准是定义 RSA 表达方法的标准。ASN.1 也包含在这个标准中。
再回到 openssl ,研究 RSA 是为了可以从 PEM 导出 RSA * 变量,存入内存中以备使用。 PEM转成RSA*, 需要使用 openssl 的接口来转换。
为什么openssl既然有了PEM文件的RSA接口,又要定义EVP_PKEY接口呢?为什么既要有BIO方式存取,也要有FILE方式存取呢?
首先,openssl包含了许多非对称加密算法,每种算法都可以定义自己存取接口。同时,openssl定义了一种统一的接口方式,那就是EVP_PKEY存取接口,这种结构体可以保存各种不同的加密结构体,用同样的结构体保存不同的加密结构体 。事实上,RSA的接口其实调用了EVP_PKEY的接口。因此,各种不同的非对称加密算法,就可以用同一个EVP的底层接口来实现,上层再次封装。
同样,openssl有自己的ssl,它定义了自己的一套文件操作方式,那就是BIO,BIO既可以封装用于网络通信的socket,也可以用于文件读取,而且还能够用于加密以及非加密的socket连接。正是如此,所以它既支持FILE存取,也支持BIO存取。看源码就可以看出,其实file的操作就是对bio进行一次封装。
上面分析了 RSA 密钥的表达结构,以及 openssl 两种接口的关系。下面是另一个让人疑惑的问题。直接说结论吧:
对于 openssl genrsa -out key.pem 2048 生成的私钥文件,以及 openssl rsa -in mykey.pem -pubout > mykey.pub 生成的公钥文件,使用下面的函数分解出公私鉏。
PEM_read_RSAPrivateKey
PEM_read_RSA_PUBKEY
而使用 openssl rsa -in key.pem -RSAPublicKey_out -out plainPub.key 导出的公钥文件才能用下面的函数:
PEM_read_RSAPublicKey
参考
https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/utility/dumpRSAPublicKey.cchromium.googlesource.com 关于openssl:使用RSA私钥生成公钥? | 码农家园www.codenong.com PKCS #1 v2.1 RSA 算法标准wenku.baidu.com 关于openssl加解密文件的几个API_晚起的鸟的博客-CSDN博客blog.csdn.net