OpenSSL(1)之介绍及其命令行工具的基本使用

OpenSSL(1)之介绍及其命令行工具的基本使用

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

介绍

在计算机网络上,OpenSSL 是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连线者的身份。这个包广泛被应用在互联网的网页服务器上。

其主要库是以 C 语言所写成,实现了基本的加密功能,实现了 SSL 与 TLS 协议。OpenSSL 可以运行在 OpenVMS、 Microsoft Windows 以及绝大多数类 Unix 操作系统上(包括 Solaris,Linux,Mac OS X 与各种版本的开放源代码 BSD 操作系统)。它也提供了一个移植版本,可以在 IBM i(OS/400)上运作。

虽然此软件是开放源代码的,但其许可书条款与 GPL 有冲突之处,故 GPL 软件使用 OpenSSL 时(如 Wget)必须对 OpenSSL 给予例外。

OpenSSL 包含一个命令行工具用来完成 OpenSSL 库中的所有功能,更好的是,它可能已经安装到你的系统中了。

OpenSSL 是一个强大的安全套接字层密码库,Apache 使用它加密 HTTPS,OpenSSH 使用它加密 SSH,但是,你不应该只将其作为一个库来使用,它还是一个多用途的、跨平台的密码工具。

背景技术

SSL 是 Secure Sockets Layer(安全套接层协议)的缩写,可以在 Internet 上提供秘密性传输。Netscape 公司在推出第一个 Web 浏览器的同时,提出了 SSL 协议标准。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。已经成为 Internet 上保密通讯的工业标准。

SSL 能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL 协议要求建立在可靠的传输层协议(TCP)之上。SSL 协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET 等)能透明地建立于 SSL 协议之上。SSL 协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

安全信道特性

数据保密性

信息加密就是把明码的输入文件用加密算法转换成加密的文件以实现数据的保密。加密的过程需要用到密钥来加密数据然后再解密。没有了密钥,就无法解开加密的数据。数据加密之后,只有密钥要用一个安全的方法传送。加密过的数据可以公开地传送。

数据完整性

加密也能保证数据的一致性。例如:消息验证码(MAC),能够校验用户提供的加密信息,接收者可以用 MAC 来校验加密数据,保证数据在传输过程中没有被篡改过。

安全验证

加密的另外一个用途是用来作为个人的标识,用户的密钥可以作为他的安全验证的标识。SSL 是利用公开密钥的加密技术(RSA)来作为用户端与服务器端在传送机密资料时的加密通讯协定。

历史

OpenSSL 计划在 1998 年开始,其目标是发明一套自由的加密工具,在互联网上使用。OpenSSL 以 Eric Young 以及 Tim Hudson 两人开发的 SSLeay 为基础,随着两人前往 RSA 公司任职,SSLeay 在 1998 年 12 月停止开发。因此在 1998 年 12 月,社群另外分支出 OpenSSL,继续开发下去。

OpenSSL 管理委员会当前由 7 人组成,有 13 个开发人员具有提交权限(其中许多人也是 OpenSSL 管理委员会的一部分)。只有两名全职员工(研究员),其余的是志愿者。

该项目每年的预算不到 100 万美元,主要依靠捐款。 TLS 1.3 的开发由 Akamai 赞助。

主要版本发布节点如下:

版本 发布时间 备注 最近更新版本
旧版本,不再支持: 0.9.1 1998年12月23日
  • OpenSSL项目的正式开启
0.9.1c(1998年12月23日)
旧版本,不再支持: 0.9.2 1999年3月22日
  • 取代0.9.1c
0.9.2b(1999年4月6日)
旧版本,不再支持: 0.9.3 1999年5月25日
  • 取代0.9.2b
0.9.3a(1999年5月27日)
旧版本,不再支持: 0.9.4 1999年8月9日
  • 取代0.9.3a
0.9.4(1999年4月9日)
旧版本,不再支持: 0.9.5 2000年2月28日
  • 取代0.9.4
0.9.5a(2000年4月1日)
旧版本,不再支持: 0.9.6 2000年9月24日
  • 取代0.9.5a
0.9.6m(2004年3月17日)
旧版本,不再支持: 0.9.7 2002年12月31日
  • 取代0.9.6m
0.9.7m(2007年2月23日)
旧版本,不再支持: 0.9.8 2005年7月5日
  • 取代0.9.7m
0.9.8zh(2015年12月3日)
旧版本,不再支持: 1.0.0 2010年3月29日
  • 取代0.9.8n
1.0.0t(2015年12月3日)
旧版本,不再支持: 1.0.1[7] 2012年3月14日 1.0.1u(2016年9月22日)
旧版本,不再支持: 1.0.2[8] 2015年1月22日 1.0.2u(2019年12月20日 (2019-12-20)
旧版本,不再支持: 1.1.0[9] 2016年8月25日 (2016-08-25) 1.1.0l(2019年9月10日 (2019-09-10)
当前版本: 1.1.1[11] 2018年9月11日 (2018-09-11) 1.1.1d(2019年9月10日 (2019-09-10)
格式:
旧版本
旧版本,仍被支持
当前版本
最新的预览版
未来版本

功能

基本功能

OpenSSL 整个软件包大概可以分成三个主要的功能部分:SSL 协议库、应用程序以及密码算法库。OpenSSL 的目录结构自然也是围绕这三个功能部分进行规划的。
作为一个基于密码学的安全开发包,OpenSSL 提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及 SSL 协议,并提供了丰富的应用程序供测试或其它目的使用。

辅助功能

BIO 机制是 OpenSSL 提供的一种高层 IO 接口,该接口封装了几乎所有类型的 IO 接口,如内存访问、文件访问以及 Socket 等。这使得代码的重用性大幅度提高,OpenSSL 提供 API 的复杂性也降低了很多。
OpenSSL 对于随机数的生成和管理也提供了一整套的解决方法和支持 API 函数。随机数的好坏是决定一个密钥是否安全的重要前提。
OpenSSL 还提供了其它的一些辅助功能,如从口令生成密钥的 API,证书签发和管理中的配置文件机制等等。如果你有足够的耐心,将会在深入使用 OpenSSL 的过程慢慢发现很多这样的小功能,让你不断有新的惊喜。

秘钥证书管理

密钥和证书管理是 PKI(公钥基础设施)的一个重要组成部分,OpenSSL 为之提供了丰富的功能,支持多种标准。
首先,OpenSSL 实现了 ASN.1 的证书和密钥相关标准,提供了对证书、公钥、私钥、证书请求以及 CRL 等数据对象的 DER、PEM 和 BASE64 的编解码功能。OpenSSL 提供了产生各种公开密钥对和对称密钥的方法、函数和应用程序,同时提供了对公钥和私钥的 DER 编解码功能。并实现了私钥的 PKCS#12 和 PKCS#8 的编解码功能。OpenSSL 在标准中提供了对私钥的加密保护功能,使得密钥可以安全地进行存储和分发。
在此基础上,OpenSSL 实现了对证书的 X.509 标准编解码、PKCS#12 格式的编解码以及 PKCS#7 的编解码功能。并提供了一种文本数据库,支持证书的管理功能,包括证书密钥产生、请求产生、证书签发、吊销和验证等功能。
事实上,OpenSSL 提供的 CA 应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书管理的大部分机制。

算法

OpenSSL 实现了 SSL 协议的 SSLv2 和 SSLv3,支持了其中绝大部分算法协议。OpenSSL 也实现了 TLSv1.0,TLS 是 SSLv3 的标准化版,虽然区别不大,但毕竟有很多细节不尽相同。

对称加密

OpenSSL 一共提供了 8 种对称加密算法,其中 7 种是分组加密算法,仅有的一种流加密算法是 RC4。这 7 种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES 使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是 128 位,其它算法使用的则是 64 位。事实上,DES 算法里面不仅仅是常用的 DES 算法,还支持三个密钥和两个密钥 3DES 算法。

非对称加密

OpenSSL 一共实现了 4 种非对称加密算法,包括 DH 算法、RSA 算法、DSA 算法和椭圆曲线算法(EC)。DH 算法一般用于密钥交换。RSA 算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA 算法则一般只用于数字签名。

信息摘要

OpenSSL 实现了 5 种信息摘要算法,分别是 MD2、MD5、MDC2、SHA(SHA1)和 RIPEMD。SHA 算法事实上包括了 SHA 和 SHA1 两种信息摘要算法。此外,OpenSSL 还实现了 DSS 标准中规定的两种信息摘要算法 DSS 和 DSS1。

心脏出血漏洞

OpenSSL 1.0.1 版本(不含 1.0.1g)含有一个严重漏洞,可允许攻击者读取服务器的内存信息。该漏洞于 2014 年 4 月被公诸于世,影响三分之二的活跃网站。

发现

2014 年 4 月 8 日,OpenSSL 的大漏洞曝光。这个漏洞被曝光的黑客命名为“heartbleed”,意思是“心脏流血”——代表着最致命的内伤。利用该漏洞,黑客坐在自己家里电脑前,就可以实时获取到约 30% https 开头网址的用户登录账号密码,包括大批网银、购物网站、电子邮件等。

“心脏流血”首先被谷歌(微博)研究员尼尔·梅塔(Neel Mehta)发现,它可从特定服务器上随机获取 64k 的工作日志,由于数据是随机获取的,所以攻击者也不一定可以获得想要的信息,因此整个过程如同钓鱼,攻击可能一次次持续进行,大量敏感数据可能泄露。由于一台服务器的密钥也记录在其工作日志中,并且在大量数据中可被轻易辨别,因此将是首当其冲的获取目标,获取密钥后,攻击者可以掌握某网站或服务的实时流量情况,甚至可以破解被加密的以往流量日志。

安全专家介绍说,OpenSSL 此漏洞堪称网络核弹,网银、网购、网上支付、邮箱等众多网站受其影响。无论用户电脑多么安全,只要网站使用了存在漏洞的 OpenSSL 版本,用户登录该网站时就可能被黑客实时监控到登录账号和密码。

根据相关媒体的报导,研究人员发现 OpenSSL 漏洞遍及全球互联网公司,并为其起了个形象的名字“心脏出血”,中国超过 3 万台主机受波及,国内网站和安全厂商技术人员为检查、抢修彻夜未眠。

成因

此次漏洞的成因是 OpenSSL Heartbleed 模块存在一个 BUG,当攻击者构造一个特殊的数据包,满足用户心跳包中无法提供足够多的数据会导致 memcpy 把 SSLv3 记录之后的数据直接输出,该漏洞导致攻击者可以远程读取存在漏洞版本的 OpenSSL 服务器内存中长达 64K 的数据。

“心脏流血”这个名字听起来有点夸张,但这个漏洞的威力似乎当得起它的名字。不管是从可能感染的电脑数量还是从可能被泄露的数据规模,“心脏流血”的破坏力都超过在 2014 年早些时候狠狠羞辱了苹果公司的“GoToFail”漏洞。“心脏流血”漏洞可以帮助黑客获得打开服务器的密钥,监听服务器数据和流量。更糟糕的是,这并不是一个新的漏洞,“心脏流血”其实已经存在两年了,但具体何时被人发现其危险性尚不得而知。

补救措施

在各个网站尚未解决安全漏洞的近两天,用户尽量不登录或者少登录涉及资金、个人隐私的网站或系统,已经多次登录的用户请尽快修改密码、绑定手机、设置支付密码,最好采用手机令牌类软件如号令手机令牌等,确保通过实时变化的动态口令保障账号安全。

代码安全审计机构 NCC Group 将开始参与到 OpenSSL 的代码审计当中。NCC 首席安全工程师的描述,OpenSSL 已经对代码进行了重构,新的代码已经足够稳定并且很快会取代现有版本。而 NCC 在代码审计中将会专注于 TLS stacks 方面的安全问题,包含 protocol flow、state transitions 和 memory management。除 NCC Group 之外,其它学术机构、商业分析公司、认证机构和个人都会参与 OpenSSL 各方面代码审计。

此上内容摘自百度百科、维基百科。

使用

以 CentOS 6/7 为例,OpenSSL 程序包已经默认安装了,我们主要要学习的就是它的命令行工具的使用。

OpenSSL 的命令行工具主命令就是 openssl,其各种功能主要是通过其子命令来完成的,我们可以通过如下命令查看其支持的子命令:

$ openssl ?
openssl:Error: '?' is an invalid command.

Standard commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dh                
dhparam           dsa               dsaparam          ec                
ecparam           enc               engine            errstr            
gendh             gendsa            genpkey           genrsa            
nseq              ocsp              passwd            pkcs12            
pkcs7             pkcs8             pkey              pkeyparam         
pkeyutl           prime             rand              req               
rsa               rsautl            s_client          s_server          
s_time            sess_id           smime             speed             
spkac             ts                verify            version           
x509              

Message Digest commands (see the `dgst' command for more details)
md2               md4               md5               rmd160            
sha               sha1              

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       base64            bf                
bf-cbc            bf-cfb            bf-ecb            bf-ofb            
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb  
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc          
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb         
des               des-cbc           des-cfb           des-ecb           
des-ede           des-ede-cbc       des-ede-cfb       des-ede-ofb       
des-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofb      
des-ofb           des3              desx              idea              
idea-cbc          idea-cfb          idea-ecb          idea-ofb          
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc           
rc2-cfb           rc2-ecb           rc2-ofb           rc4               
rc4-40            rc5               rc5-cbc           rc5-cfb           
rc5-ecb           rc5-ofb           seed              seed-cbc          
seed-cfb          seed-ecb          seed-ofb          zlib 

如上,其子命令可分为三类:

  • 标准命令,OpenSSL 为完成基本功能而设计的命令,如生成随机数(rand)、查看程序版本(version)等;
  • 消息摘要命令,对多种消息摘要算法提供支持;
  • 加密命令,对多种加密算法提供支持;

下面对其常用的子命令命令做一下基本演示。

对称加密

openssl 子命令中常用的对称加密子命令的是 enc,常用算法有 3desaesblowfishtwofish
它的具体说明文档可通过 man enc查看,看下面示例。

例:加密以 3des 算法加密 /etc/fstab,加盐 123,将其加密后的内容输出到 fstab.ciphertext,然后解密其内容输出到当前目录的 fstab 文件中。

# 加密
$ openssl enc -e -des3 -S '123' -in /etc/fstab -out fstab.ciphertext
enter des-ede3-cbc encryption password:
Verifying - enter des-ede3-cbc encryption password:
# 解密
$ openssl enc -d -des3 -S '123' -in fstab.ciphertext -out fstab
enter des-ede3-cbc decryption password:

其中 -des3 是指定算法,加密命令中看到的那些算法基本上都可以调用。

单向加密(消息摘要)

其实在之前我们应该已经使用过一些单向加密的命令,如 md5sumsha1sumsha224sumsha256sum 等,对于这些单向加密算法 openssl 使用 dgst 子命令提供了支持,其具体说明文档可通过该 man dgst 查看,下面看示例。

例:使用 MD5 算法对 /etc/fstab 进行单向加密,并以十六进制格式输出内容,然后使用 md5sum 对比其输出内容。

$ openssl dgst -md5 -hex /etc/fstab
MD5(/etc/fstab)= bb834f634038935c851ef2a8ebe87103
$ md5sum /etc/fstab
bb834f634038935c851ef2a8ebe87103  /etc/fstab

MAC:Message Authentication Code,单向加密的一种延伸应用,用于实现在网络通信中保证所传输的数据的完整性。
通常使用 HMAC 算法,HMAC 的实现机制有两种,第一种叫 CBC-MAC,第二种叫 HMAC(使用 md5 或 sha1 算法)。

生成用户密码

我们知道,用户密码直接明文保存在服务器中是不可取的,所以 openssl 也提供了对密码进行加密的子命令 passwd,通过 man sslpasswd 可以查看到其具体使用说明,下面看示例:

例:以 MD5 算法加密 123,加密盐为 zze.xyz

$ openssl passwd -1 -salt zze.xyz 123
$1$zze.xyz$ChpemUsOEd5mA4Xb0A2eR0

生成随机数

opensslrand 子命令可用来生成随机数,其具体使用说明可通过 man sslrand 查看,下面看示例。

例:生成长度为 8 的随机十六进制数和 base64 编码的随机字符。

$ openssl rand -hex 4
a47771f6
$ openssl rand -base64 4
z1QOaA==

这里 4 指定的是字节数。

生成秘钥对

使用 genrsa 命令可以基于 RSA 算法生成私钥,然后可以使用 rsa 子命令来生成私钥对应的公钥,其具体使用说明可通过 man genrsaman rsa 查看,下面看示例。

例:生成长度为 2048 的私钥,然后生成其对应公钥。

# 生成私钥
$ (umask 077; openssl genrsa -out rsakey.private 2048)
Generating RSA private key, 2048 bit long modulus
..........................+++
...................................+++
e is 65537 (0x10001)
# 根据私钥生成公钥
$ openssl rsa -in rsakey.private -pubout 
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8TVUwjR+dthAwDH844K
ToOgNDUcpcT2xRyIKXKsBsXlijFYLVbuJVCHd2YFbmf3XDOzaJwwqvKX7vMv4lGL
wY/aNmBdvVvo3UyTLBeMOMHPl0z1dDY0sv9NuyUjWW+WqKK5n/CK1zZecl9Nolxg
0usFok0nsRSAInUhsqUFjVykYoJKTtKgOjpFJ+pd0d+bXjs263nrmVBTmxwD8++J
D/IRvdc5hnxzCnIhfLXbWXvlAahCJ28I4gh/jH0lzlbGV7O9Zi7VgAD1+VtlrxTo
/pjl+99AFh6s0lqMlxULZoRoNy9ECOMrFmpvysyQrREc0FYziQHl69aQr1fp1yIP
/QIDAQAB
-----END PUBLIC KEY-----

由于默认生成的私钥文件对其它用户可读,所以我们在生成私钥后需要修改其仅属主可读。
而在上述生成私钥的命令中,() 中的命令会独立在子 Shell 中运行,我们更改子 Shell 的 umask 码对当前主 Shell 进程的 umask 码不影响,从而实现了一条命令保证其生成的私钥文件权限私有。


上述已经了解了 OpenSSL 的基本用法,除此之外 OpenSSL 还可以用来生成私有 CA,并且具有发证、签证等功能,这部分内容后续在聊。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/linux-cmd-openssl.html

Buy me a cup of coffee ☕.