2019独角兽企业重金招聘Python工程师标准>>>

作者: 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,A6F8DD9D1D994363907C278CDF9B644CMfsPjXK6izOmmzMseG3M2aBKque20ao13+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

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

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

转载于:https://my.oschina.net/fenying/blog/786238

OpenSSL 之 RSA 相关命令学习笔记相关推荐

  1. linux 安装jeakens_Chapter 2. OpenSSL的安装和配置学习笔记

    Chapter 2. OpenSSL的安装和配置学习笔记 2.1 在linux上面安装OpenSSL 我还是做点No paper事情比较在行,正好和老师的课程接轨一下. 以前尝试过在Windows上面 ...

  2. 【Redis数据库】命令学习笔记——发布订阅、事务、脚本、连接等命令汇总

    本篇基于redis 4.0.11版本,学习发布订阅.事务.脚本.连接的相关命令. Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 序号 ...

  3. 删除mysql指令_MySQL常用命令学习笔记

    本文转载自[微信公众号:WalkingCloud,ID:WalkingCloud2018]经微信公众号授权转载,如需转载与原文作者联系 MySQL常用命令学习笔记 一.数据库相关操作 1)创建数据库 ...

  4. 软考网络管理员-华为设备命令学习笔记

    华为设备命令学习笔记 文章目录 一. 网络设备基础知识 1.1 网络设备操作系统 1.2 常见设备配置方式 1.3 基础知识 二. 基础命令与二层设备配置 2.1 配置模式 2.2 基本命令 2.3 ...

  5. Linux命令学习笔记

    Linux命令学习笔记 1 前言 1.1 系统版本 1.2 终端切换 1.3 快捷键 1.4 帮助文档 1.5 关机重启 2 目录命令 2.1 当前目录 pwd 2.2 切换目录 cd 2.3 查看目 ...

  6. linux之awk命令学习笔记

    Linux之awk命令学习笔记 前言 AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, ...

  7. 多项式相关操作学习笔记

    多项式相关操作学习笔记 标签: 多项式 说在前边 记录一下相关的多项式操作,顺便存个模板.(多点求值之后的部分,有点写不动了...留坑留坑 多项式 定义 给定一个环\(R\)(\(R\)通常是交换环, ...

  8. linux基础命令学习笔记(二)

    linux基础命令学习笔记(二) 1.kill :终止进程  kill pid (唯一标示一个进程) kill -9  强制终止  kill -15 命令未结束不能终止 # ps aux 查看所有进程 ...

  9. window的dos命令学习笔记 七

    文章目录 一.dos历史学习笔记(后期整合到这里,我想能学到这里的应该不多了,嘿嘿,加油) 二.执行状态返回值(`%errorlevel%`,和shell中`$?`相似): 三.视窗 1.color ...

最新文章

  1. 软件测试基础--笔记6
  2. 01.移动先行之谁主沉浮----我的第一个程序
  3. 分布式系统熔断机制的工作原理
  4. 【Kotlin】Kotlin 中使用 ButterKnife ( 仅用于适配 Kotlin 语言 | 不推荐新项目使用 )
  5. 获取某个view的高度或者宽度
  6. C语言深度剖析书籍学习记录 第七章 文件结构
  7. Python中的Dask数组
  8. 再见李佳奇,菜鸟哥用Python也能帮小姐姐选择口红啦,快来看看!!
  9. 国家邮政局:对刷单、贩卖快递盲盒等进行清理整顿
  10. 芯片之战!亚马逊、Google、苹果群起“围攻”英特尔
  11. python清理浏览器文件_URL可以在浏览器或wget中正常工作,但是从Python或cURL中清空...
  12. 闰年,闰月对应的天数快速记忆法
  13. matlab z rc电路,基于MATLAB模拟RC电路的暂态过程.pdf
  14. 电子计算器按键的功能
  15. 记事狗微博php,记事狗微博系统_366rtc
  16. 系统模块化备援 服务器,无法登录到 CMM 以进行英特尔® 模块化服务器系统
  17. 阿里巴巴java工程师应聘条件_【全国】—前端/Java工程师—阿里巴巴(长期招聘)...
  18. 大数据风控是在做什么?
  19. java代码审计_Java代码审计入门篇
  20. CTF---basecrack---Base编码分析工具安装详解

热门文章

  1. GDCM:读取两个DICOM文件保存在另外dicom文件中的测试程序
  2. Boost::context模块callcc的jump测试程序
  3. boost::callable_traits的qualified_class_of_t的测试程序
  4. DCMTK:OFStandard中base64代码的测试程序
  5. Qt Creator使用命令行选项
  6. Qt Creator配置编辑器
  7. map 和set 有什么区别,分别又是怎么实现的
  8. QT的QMediaControl类的使用
  9. 经典C语言程序100例之二二
  10. 怎么用python扫描主机_python扫描主机开放的端口