文档章节

OpenSSL 之 RSA 相关命令学习笔记

开源中国红薯批发商
 开源中国红薯批发商
发布于 2016/11/11 13:37
字数 1572
阅读 391
收藏 1

作者: Angus.Fenying <i.am.x.fenying@gmail.com>

日期: 2016-11-10 10:35 PM

本文介绍 OpenSSL 命令行进行 RSA 加密、解密、签名、验证的操作,但不涉及 RSA 算法原理解析,如有兴趣,可以阅读阮一峰的《RSA算法原理》。如果你只想知道 RSA 是什么,那么你只要记住:RSA 是一种加密算法,使用两个密钥,一个叫公钥,一个 叫私钥,使用公钥加密的密文只有使用私钥才可以解密,反之亦然。

Section 0: 生成随机文件

由于 OpenSSL 创建密钥文件是随机生成的,因此有必要为之提供一份随机数据源。

可以用 openssl 的 rand 命令创建一个 64MB 的随机文件,保存为文件 randSrc.bin

openssl rand -out ./randSrc.bin 67108864

还可以使用 -base64 或者 -hex 两个参数之一指定输出格式为 BASE64 或者 HEX。

Section 1: 生成一个密钥文件

小贴士:

  1. 根据目前的普遍需求,应当使用 AES256 为加密标准。
  2. 通常 RSA 私钥文件命名为 name.pem,公钥文件名为 name_pub.pem
  3. OpenSSL 生成的密钥文件默认是 PEM 格式的。
openssl genrsa \
    -rand randSrc.bin \
    -aes256 \
    -out rsa.pem 2048

这个命令的意思是:

  • genrsa: 生成 RSA 密钥文件。
  • -aes256: 使用 AES256 算法加密生成的密钥文件, 因此你需要输入加密用的密码(并记住)。
  • -rand randSrc.bin 使用文件 randSrc.bin 作为随机数来源。
  • -out rsa.pem: 将生成的密钥文件保存为 rsa.pem
  • 2048: 生成 2048 Bits 的 RSA 密钥文件。

2048 Bits 是指 RSA 算法里 N 的长度,而不是说公钥和私钥都是 2048 Bits。

生成文件样例:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,A6F8DD9D1D994363907C278CDF9B644C

MfsPjXK6izOmmzMseG3M2aBKque20ao13+oFg/JdJtlCK0Vb11hLqq8h/ICnY3lI
z1xuBKiXVykl521YumeTS6C+WtSkb71cy1u6lHBwdO44tWxklEqcl1sLYIWKyNaB
VgKmS4BhfuUq8XlSt3LnuQT/BJWPP7+GUUaZG6/stMWAx+XBg9mMahxGCqo7aRcz
...............
nLGRE27iklwGgSagaK40FDiSe69HcIBkHCUQYaYtXQzHNgjoQRkcotzo+vxM7XcL
5y5DHwA8IFwt9c5f14lxZ2cXF9p54JA3UMy+T7XggINDgBFuOPR/U3eBS2x6hHW6
eoGX+khw+s5atpNJaF4s6n2ViDseQsW+b8NfSdlX0j5f5xSasFcYgFsDZtBy/FqZ
-----END RSA PRIVATE KEY-----

这是一个密钥文件,而不是一个纯粹的私钥文件,它包含了完整的密钥信息,即是说,里面 既有公钥也有私钥。但是只能把它当成私钥使用,公钥部分请参考 Section 3

Section 2: 去除密钥文件的密码

Section 1 生成的密钥文件中提取没有密码的密钥文件,以便给 Nginx 等服务器使用。

openssl rsa -in rsa.pem -out rsa_pri.pem

Section 3: 根据私钥生成公钥

Section 1 生成的私钥文件中提取公钥文件。

openssl rsa -in rsa.pem -pubout -out rsa_pub.pem

Section 4: 使用公钥加密

RSA 加密和解密都是使用 openssl 的 rsautl 命令。

Section 3 里面生成了公钥文件 rsa_pub.pem,下面使用它进行加密。 (先生成个数据文件)

echo 1234567890 > test.txt
md5sum test.txt
openssl rsautl \
    -encrypt \
    -in test.txt \
    -out test.secret \
    -pubin \
    -inkey rsa_pub.pem

可以看到源文件 test.txt 的 MD5 值为 7c12772809c1c0c3deda6103b10fdfa0

源文件 test.txt 只有 10 个字节大小,但是加密结果文件 test.secret* 居然有 256 字节(2048 位长),这是因为 RSA 密钥是 2048 位长度的,而 RSA 加解密算法的操作 单位必须和密钥长度一致。所以加密结果的大小一定和密钥长度的一致。所以加密长度必须小于 密钥长度 - 填充长度

关于填充数据,默认使用 PKCS#1 v1.5 填充格式。

Section 5: 使用私钥解密

Section 1 里面生成了密钥文件 rsa.pem,下面使用它进行加密。

openssl rsautl -decrypt -in test.secret -out test.raw -inkey rsa.pem
md5sum test.raw

这里使用的是带密码的密钥文件,因此需要输入 AES 密码先把密钥文件解密出来。如果使用的是 Section 2 中生成的无密码密钥文件,那么则不需要输入密码了。

可以看到解密出来的文件 test.raw 的 MD5 值为 7c12772809c1c0c3deda6103b10fdfa0

Section 6: 使用私钥签名

加解密是使用公钥加密,私钥解密,因为公钥是公开的,私钥是保密的。签名和校验则反过来, 私钥签名,公钥校验。

这里假设你要发送消息给你朋友,消息存在文件 test.txt 中,你已经拥有了你朋友的 公钥文件 fr_pub.pem

那么先用他的公钥对文件进行加密:

openssl rsautl -encrypt -in test.txt -out test.msg -pubin -inkey fr_pub.pem

得到了加密后的文件 test.msg,下面使用你自己的私钥进行签名。

先用 SHA256 算法生成文件的哈希校验码:

openssl sha256 -out test.hash test.msg

得到了哈希校验文件 test.hash,内容如下:

SHA256(test.msg)= ************************

下面使用 RSA 私钥对其进行签名:

openssl pkeyutl \
    -sign \
    -in test.hash \
    -out test.sign \
    -inkey rsa_raw.pem

或者

openssl rsautl \
    -sign \
    -in test.hash \
    -out test.sign \
    -inkey rsa_raw.pem

RSA 私钥签名的实质是:使用 RSA 私钥对数据的哈希校验码进行加密,这样就可以用 对应的 RSA 公钥解密得到数据的哈希校验码。

得到了签名后的文件 test.sign,将它和 test.msgrsa_pub.pem 一起发给你的朋友。

Section 7: 使用公钥校验

现在你的朋友收到了你发给他的三个文件,分别是:公钥、签名、消息。现在他怎么确定 消息是发给他的呢?当然是使用公钥校验啦。

首先,他同样使用 openssl 生成文件 test.msg 的哈希校验码。

openssl sha256 -out test.hash test.msg

然后使用你的公钥文件对其进行校验:

openssl pkeyutl \
    -verify \
    -in test.hash \
    -sigfile test.sign \
    -pubin \
    -inkey rsa_pub.pem

如果校验通过,则会看到提示:Signature Verified Successfully

然后他再使用他的私钥解密 test.msg 文件即可得到你发给他的消息了。

这里不使用 openssl rsautl -verify 命令,因为 rsautl-verify 指令 仅仅是将输入的文件用公钥解密,但不与计算出来的哈希校验码进行比较,不如 pkeyutl 的 -verify 方便:

openssl rsautl \
    -verify \
    -in test.sign \
    -pubin \
    -inkey rsa_pub.pem

前面说了,rsa.pem 里面既包含私钥又包含公钥,这里可以小小地证明一下。 直接使用 rsa_raw.pem 文件进行签名校验。

openssl pkeyutl \
    -verify \
    -in test.hash \
    -sigfile test.sign \
    -pubin \
    -inkey rsa_raw.pem

如何,结果是不是一样呢?

那么,问题来了。如果传输过程被人拦截了怎么办?这就是下一篇文章的内容了。

© 著作权归作者所有

共有 人打赏支持
开源中国红薯批发商
粉丝 14
博文 12
码字总数 12918
作品 0
深圳
程序员
keytool 工具应用分析与整理

文前说明 作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。 本文仅供学习交流使用,侵权必删。 不用...

羽杰
2017/06/26
0
0
openssl的应用及创建CA

openssl命令行工具: 众多的子命令实现各种安全加密功能; ]# openssl ? 显示的内容有 Standard commands(标准命令) enc, dgst, ca, req, genrsa, rand, rsa, x509, passwd, ... Message Di...

Vayne36
06/26
0
0
CentOS 7.4 Tengine安装配置详解(五)

十四、配置Tengine支持HTTPS 1、演示环境: 备注:Tengine和CA可以部署于同一台服务器 2、修改配置文件nginx.conf,创建基于主机名的虚拟主机: server { listen 80; server_name web.vhosts...

Marion0728
06/26
0
0
Git的.ssh文件夹内容介绍

文章作者:Tyan 博客:noahsnail.com | CSDN | 简书 1. rsa与rsa.pub 首先是rsa与rsa.pub是如何产生的,产生的命令如下: 解释:是产生密钥,密钥有两种类型rsa和dsa两种,用来指定密钥类型,...

Quincuntial
2016/10/23
0
0
ssh-keygen的学习总结

ssh-keygen介绍 维基百科上关于ssh-keygen的介绍如下: ssh-keygen is a standard component of the Secure Shell (SSH) protocol suite found on Unix and Unix-like computer systems use......

潇湘隐者
08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sqlserver 2008 r2 直接下载地址(百度云)

之前下载的sqlserver2008发现不能附加,就卸载了,重新找到了sqlserver2008R2的百度云资源 卸载sqlserver2008还是有点麻烦,不过就是需要删除注册表中的信息 自己来回卸载了3次终于重装sqlse...

dillonxiao
30分钟前
1
0
[Java]JVM调优总结 -Xms -Xmx -Xmn -Xss

JVM调优总结 -Xms -Xmx -Xmn -Xss 博客分类: Java General JVM应用服务器电信CMS算法 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可...

morpheusWB
41分钟前
1
0
C++ std::function 和 std::bind

C++11提供了std::function和std::bind两个工具,用于引用可调用对象。这些可调用对象包括 普通函数,Lambda表达式,类的静态成员函数,非静态成员函数以及仿函数等。引用可调用对象,可以用于...

yepanl
今天
2
0
python:可迭代对象的索引

关于 python的range的用法: 注意是[ 开始,结束)的半开区间,不包括结束 http://www.runoob.com/python/python-func-range.html import collectionsfrom collections import Iterable字符串......

Oh_really
今天
3
0
docker-compose ,docker-stack

1.例子 version: "3"services: php: image: registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5 ports: - "38080:80" networks: - my_php_mysql volum......

chenbaojun
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部