OpenSSL使用总结

Last Updated: 2024-01-02 11:09:39 Tuesday

-- TOC --

OpenSSL是网络安全的心脏,它也是一个特别重要的工具。

openssl

官网:https://www.openssl.org/

OpenSSL历史

OpenSSL计划从1998年开始,其目标是发明一套自由的加密工具,在互联网上使用。

OpenSSL以Eric Young以及Tim Hudson两人开发的SSLeay为基础,随着两人前往RSA公司任职,SSLeay在1998年12月停止开发。因此在1998年12月,社区另外拉出OpenSSL分支,继续开发下去。

心脏出血漏洞

心脏出血漏洞(英语:Heartbleed Bug),简称为心血漏洞,是一个出现在加密程序库OpenSSL的安全漏洞,该程序库广泛用于实现互联网的传输层安全(TLS)协议。它于2012年被引入了OpenSSL中,2014年4月首次向公众披露。只要使用的是存在缺陷的OpenSSL版本,无论是服务器还是客户端,都可能因此而受到攻击。

2012年2月,传输层安全(TLS)和数据报传输层安全(DTLS)协议的心跳扩展成为了标准,RFC6520。它提供了一种无需每次都重新协商连接,就能测试和保持安全通信链路的方式。2011年,RFC的作者之一,当时杜伊斯堡-埃森大学的博士生罗宾·赛格尔曼(Robin Seggelmann)为OpenSSL实现了此心跳扩展。赛格尔曼向OpenSSL发出推送请求之后,他的更改由OpenSSL四位核心开发者之一的斯蒂芬·N·汉森(Stephen N. Henson)审核。汉森未能注意到赛格尔曼实现中的错误,于2011年12月31日将有缺陷的代码加入了OpenSSL的源代码库。2012年3月14日,OpenSSL 1.0.1版发布,漏洞开始传播。心跳支持默认是启用的。

受影响的OpenSSL版本为1.0.1至1.0.1f(含)。

RFC6520心跳扩展定义了一种测试TLS/DTLS安全通信链路的方法,允许连接一端的计算机发送“心跳请求”消息,消息包含有效载荷(通常是文本字符串),附带有效载荷的长度(用16位整数表示)。随后,接收方计算机必须发送完全相同的有效载荷以返回给发送方。

受影响的OpenSSL版本根据请求消息中的长度字段分配内存缓冲区,用于存储要返回的消息,而未考虑消息中有效载荷的实际长度。因为缺少边界检查,返回的消息可能不仅包括有效载荷,还含有其他恰巧在已分配缓冲区中的信息。

因此,通过构造出载荷短、长度却很大的请求,向存在缺陷的一方(通常是服务器)发送畸形心跳包,利用心脏出血漏洞,引起受害者的回应,这样,攻击者便可读取到受害者内存中至多64KB的信息,而这块区域先前OpenSSL有可能已经使用过。例如,正常的心跳请求可能会要求对方返回4个字符的单词bird,那对方就返回bird。“心脏出血请求”(恶意的心跳请求)如“返回500个字符的单词‘bird’”,会导致受害者返回“bird”,紧接着是恰储存在Server活跃内存中的其它496个字符。这样,攻击者便可能会收到敏感数据,从而危及受害者其它安全通信的保密性。虽然攻击者能控制返回的内存块大小,但却无法决定它在Server内存中的位置,因而不能指定要返回的内容。

编译安装OpenSSL

一般Linux系统中都有自带OpenSSL,不过有的时候版本与需求不匹配,此时就只能自己编译安装了。

下载:https://github.com/openssl/openssl/releases

然后:

$ sudo dnf install perl
$ ./config --prefix=/usr/local/openssl
$ make && sudo make install
$ sudo ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl

配置ldconfig

对于OpenSSL来说,没有这一步,会有一个找不到共享库的错误提示:

$ openssl
openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

可以在/etc/ld.so.conf文件中增加一行:

/usr/local/openssl/lib

然后执行:

$ sudo ldconfig -v  # -v means verbose

查看OpenSSL版本

$ openssl version
OpenSSL 1.1.1f  31 Mar 2020
$ openssl
OpenSSL> version
OpenSSL 1.1.1f  31 Mar 2020
OpenSSL> exit

OpenSSL工具的命令行风格很特别!

创建RSA私钥和公钥

学习资料:RSA算法原理

创建RSA私钥

$ openssl genrsa
Generating RSA private key, 2048 bit long modulus (2 primes)
.............+++++
.+++++
e is 65537 (0x010001)
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAvnJIY0Y/3uAgdjjrCtl7cumJIPmxgX4NyiXf9KKZFUIjdXUQ
V1h6Y1Croe+YNaT6Vi0X9xt2NMoeaNsOe4eErJfgKG5B6llJ1raARJsQN3Om/ciH
4kktXpKwivXLwtqnFNwmgPhXmRq9sCbbUGtwtO9QOMUi7hd7wgcsASLiTjhgiqGH
QoG+QU8s2Qfu8OylRRP68TEVzj/w8n0lAAqD2qx6RXCLwPyBgbPs1RNQAMjdbDP+
rBgkNjtNeV+3ioFUxkmTYpp6s/sP3RHO3OY0EDk/ljbCvwU9qRHqeHmmY65hHKLG
k6bDROsqbSMA5Nqiv1QgkXck7BdWBl5rviaqcwIDAQABAoIBAQCJmteU63hQ2I57
/WpO/49EG1uauO+5ydO64RztjOKhSpWGU9xH0EU2J16r9gt7j0XWKGTthiklwXix
eL4BIY0Ki/5KGEiGRJemjV0mtQfFmUnqiw8rwIYIlGL9NNZSZ1xcJSmo/EeG95xh
f+HtPIRGJ7hGHKK9d7hTHI1+EK+FpdVzfbCswfHB+s6KlXxrpiJeIGOEwmI3WNjj
IzEqbVW8t+6HGlr61L7E2RbAAUF6KY7sjl3+RN6otqIWtklGRpIfRPxeSlFV+BDy
P51uCCbhwkFB/hlaGbwTHvtDJICssYnIsd8Olv2zEMn7x6geY9GxgOdJqQ+0pX3J
TgJ9AgMJAoGBAOBxeXhBl5SGsGutlFGCEPMgg4ayhvHosokS0PR+2kCz05WtuLaQ
gEtiFOKaufMrlI+wtEGYFVVdHG00GHBe7bDphIOoX7mEKpd/z+ipT0roVI6Pl16/
brIn3QPvxjrrTkEzjFIKXu609ehijE0m3GUQxkk5n6QzQGdUUQVLnmAvAoGBANk5
I4nChLJSkx4bDfDCFW27NwKmGL2QaOK1Sv6+GlmeoP8yRtZVofnV8j5dZyKRYh7q
AGc9jC4Xa42msNhURSJqxiJCKM7c6HPak1sy+FS+xNlPwuAFY3HN7QBXsIHA52rx
I7DiGrE+SKuHkNvKg6Tc6LcXkiqQnyukCQAq1ST9AoGAe+XoWjxLQxB/P1HY+I3G
cZBXSvouiEgelpCujOmh7enXOV9nAlEOoY6JXPZxBA3gutmfCD6+OBtoX9hMTWv5
5pliL5O5FB4jrPI/gX5FaWKLmw8lToZ6wxpCZbPtSAUxc8jTA076TOfUf+426Tg0
ng3+h9mpiOlJ+kCPYU73JL0CgYBIbOevd968ghGxOP4F5wA0DPbDeFPJaIvAAwhV
NVcdyGkPjVjW/8g4v5+8MXJAsU6Q1h56TageegqPOSO/jSFb31PeekaW6krKzfbR
soXf45dIiXKFNOa6PBmoQpSEPqgqHOp0gH671/Ns1Y9z6OrJniotWbuPW5bmexPR
LXbRlQKBgAIaZQ1sXjc2KWMIFwYKPJi25Z9EmgbIOZ1JBBQd7I+otp22oXw0FGKI
yrNwObVRRwz072yTsbplHl18YvwvHK/43kcCTPBvZVnRn3p3Iz0P2BHErSZ+WSkE
R1+0gHnQcClsxEl3WjwzQWVgKvESYXyhFs3mVyKfZUpfh9IUwmm9
-----END RSA PRIVATE KEY-----

openssl genrsa,创建私钥,默认的秘钥长度为2048bit,e默认使用65537。

下面的命令,指定RSA私钥的长度为4096,并且将私钥保存到指定文件:

$ openssl genrsa 4096 > private.key
$ cat private.key

另一种命名风格:

$ openssl genrsa --out private.key 1234

创建RSA公钥

在创建私钥的时候,e的值已经被指定了,公钥就是(n,e):

$ openssl rsa -in private.key -pubout -out public.key
$ openssl rsa -in private.key --pubout > public.key

读取RSA私钥内容

前面内容已经说明,可以使用 cat 命令直接读取私钥文件的内容,不过这些内容都是Base64格式的,下面的命令可以直接显示出私钥的数字:

$ openssl genrsa 512 > pk
Generating RSA private key, 512 bit long modulus (2 primes)
............+++++++++++++++++++++++++++
.................+++++++++++++++++++++++++++
e is 65537 (0x010001)
$ openssl rsa -in pk -text
RSA Private-Key: (512 bit, 2 primes)
modulus:
    00:a1:fe:ef:e1:8e:b3:31:5d:3c:f0:75:9a:bc:ad:
    39:e7:26:d8:c1:75:d7:e4:41:55:bd:70:78:8e:fe:
    cc:94:81:a8:f0:64:7b:42:34:cb:31:ff:03:db:a9:
    37:6a:94:30:92:15:b0:ed:d5:ae:4f:c4:82:e6:46:
    0d:a4:0e:a1:a1
publicExponent: 65537 (0x10001)
privateExponent:
    17:7b:79:12:5d:39:24:82:bb:7e:af:cd:8a:64:21:
    ec:9b:f8:f7:b2:39:65:61:03:28:be:d0:fb:09:7c:
    66:5a:5a:31:4f:ca:42:f3:fb:17:e6:1e:25:ac:a5:
    3d:bb:e8:ed:e4:8a:cf:fd:fa:fe:1a:ce:a6:3f:32:
    b5:96:70:31
prime1:
    00:cf:f9:2d:03:9c:c4:e9:16:d0:c1:95:e6:8d:2a:
    b5:95:74:8d:ae:bd:cf:a5:21:fe:f6:14:68:63:9e:
    4b:06:53
prime2:
    00:c7:67:b2:09:16:8e:39:86:d4:6a:44:9b:75:79:
    ef:e3:64:bd:8f:97:cd:b0:77:3c:50:52:4d:17:bb:
    24:91:bb
exponent1:
    15:cb:73:20:31:c9:a0:f3:b7:24:d2:64:ba:de:82:
    f1:0a:a9:de:6a:1d:dc:9c:57:6f:ca:6b:b6:24:dc:
    8f:e9
exponent2:
    4d:b0:cb:1e:db:58:e2:74:f3:c1:cb:a5:3e:2a:1a:
    1a:e0:9f:32:99:14:9c:d2:77:ff:5b:71:89:f3:72:
    16:0d
coefficient:
    4c:8b:0a:91:f3:b5:53:6d:8b:ef:94:d9:82:77:e8:
    79:78:4d:96:25:eb:d9:97:1b:39:84:e1:e7:82:d0:
    cd:d0
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJBAKH+7+GOszFdPPB1mrytOecm2MF11+RBVb1weI7+zJSBqPBke0I0
yzH/A9upN2qUMJIVsO3Vrk/EguZGDaQOoaECAwEAAQJAF3t5El05JIK7fq/NimQh
7Jv497I5ZWEDKL7Q+wl8ZlpaMU/KQvP7F+YeJaylPbvo7eSKz/36/hrOpj8ytZZw
MQIhAM/5LQOcxOkW0MGV5o0qtZV0ja69z6Uh/vYUaGOeSwZTAiEAx2eyCRaOOYbU
akSbdXnv42S9j5fNsHc8UFJNF7skkbsCIBXLcyAxyaDztyTSZLregvEKqd5qHdyc
V2/Ka7Yk3I/pAiBNsMse21jidPPBy6U+Khoa4J8ymRSc0nf/W3GJ83IWDQIgTIsK
kfO1U22L75TZgnfoeXhNliXr2ZcbOYTh54LQzdA=
-----END RSA PRIVATE KEY-----

还可以加上一个 noout 参数,末尾的Base64字符串就不会显示出来。

创建CSR文件

CSR,Certificate Signing Request,是用来向CA机构申请域名证书的文件。

你需要为域名创建RSA私钥,然后用私钥创建CSR文件:

# Generate a domain private key (if you haven't already)
$ openssl genrsa 4096 > domain.key

# For a single domain
$ openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr

# For multiple domains (use this one if you want both $ www.yoursite.com and yoursite.com)
openssl req -new -sha256 -key domain.key -subj "/" -addext "subjectAltName = DNS:yoursite.com, DNS:www.yoursite.com" > domain.csr

# For multiple domains (same as above but works with openssl < 1.1.1)
$ openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

注意如何制作多域名的CSR文件!

创建自签名证书

网站使用自签名的证书,虽然浏览器会提示风险,但是用来测试是OK的。公司内部搭建FTPS服务器,也会用到自签名的CRT。

$ openssl req -new -x509 -key domain.key -out domain.crt -days 365

这个命令是交互式的,在Common Name的地方,填入domain。 -days 365表示此证书有效期为365天。(CRT证书都有有效期,Let's encrypt的证书有效期只有90天)

同时生产私钥和证书

$ openssl
OpenSSL> req -new -x509 -nodes -out server.crt -keyout server.key  -days 365
# ...
OpenSSL> exit

pem文件

一直没搞懂pem文件格式是如何定义的,只是有一个应用学会了,我在搭建FTPS服务器的时候,将私钥和证书放在一个文件里面,就成了pem文件。

$ cat ftps.crt >> ftps.key
$ mv ftps.key ftps.pem

PEM - Privacy Enhanced Mail

可用cat命令查看,文本格式,以"-----BEGIN-----"开头, "-----END-----"结尾,内容经过BASE64编码。

查看PEM格式证书的信息:$openssl x509 -in certificate.pem -text -noout

Apache Httpd服务器使用这种编码格式,Python的SSL/TLS模块使用这种格式,参考RFC1422

DER

DER - Distinguished Encoding Rules

打开看是二进制格式,不可读。

查看DER格式证书的信息:$openssl x509 -in certificate.der -inform der -text -noout

PEM和DER这两种格式也可以相互转换

将PEM转换为DER格式:$openssl req -in csr.pem -outform DER

证书编码的转换

PEM转为DER openssl x509 -in cert.crt -outform der -out cert.der

DER转为PEM openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

要转换KEY文件也类似,只不过把x509换成rsa,要转CSR的话,把x509换成req...

openssl passwd命令

这个命令可以用来生成一个shadow文件中使用的密码串,比如在制作基于busybox的启动U盘的时候,给root生成一个密码串,放入etc/shadown文件中,用于登录。

$ openssl passwd -1 'password'
$1$6NkGADUC$yLP2x0Gfc3CoBWxCLmftM1

-1 表示使用MD5加密。

Base64编解码

Base64编解码

$ echo '12345678' | openssl base64
MTIzNDU2NzgK
xinlin@K:~/test$ echo MTIzNDU2NzgK | openssl base64 -d
12345678

对文件内容进行base64编解码:

$ openssl base64 -in tb64.txt
MTIzNDU2NzgK
$ openssl base64 -in tb64.txt > tb64d.txt
$ openssl base64 -d -in tb64d.txt
12345678

RC4加解密

RC4算法在使用的时候,需要提供一个key。

$ echo 'abcdefg123456789' | openssl rc4 -nosalt > etxt
enter rc4 encryption password:
Verifying - enter rc4 encryption password:
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
[xinlin@iZ239r252v4Z test]$ openssl rc4 -nosalt -d -in etxt
enter rc4 decryption password:
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
abcdefg123456789

本文链接:https://cs.pynote.net/se/202110135/

-- EOF --

-- MORE --