title: linux-openssl
date: 2020-09-16 11:02:15
categories:
- [学习, shell]
tags: - shell
- linux
- openssl
介绍
{% note info %}
OpenSSL是一个健壮的、商业级的、功能齐全的开源工具包,用于传输层安全(TLS)协议,以前称为安全套接字层(Secure Sockets Layer, SSL)协议。协议实现基于全强度通用密码库,也可以单独使用。
openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。
<span style="color:red;">项目地址</span> <span style="color:red;">官方网址</span> <span style="color:red;">手册</span>
{% endnote %}
算法简介
{% tabs configtab, 1 %}
对称算法使用一个密钥。给定一个明文和一个密钥,加密产生密文,其长度和明文大致相同。解密时,使用读密钥与加密密钥相同。
ECB\CBC\CFB\OFB
摘要算法是一种能产生特殊输出格式的算法,这种算法的特点是:无论用户输入什么长度的原始数据,经过计算后输出的密文都是固定长度的,这种算法的原理是根据一定的运算规则对原数据进行某种形式的提取,这种提取就是摘要,被摘要的数据内容与原数据有密切联系,只要原数据稍有改变,输出的“摘要”便完全不同,因此,基于这种原理的算法便能对数据完整性提供较为健全的保障。但是,由于输出的密文是提取原数据经过处理的定长值,所以它已经不能还原为原数据,即消息摘要算法是不可逆的,理论上无法通过反向运算取得原数据内容,因此它通常只能被用来做数据完整性验证。
如今常用的“消息摘要”算法经历了多年验证发展而保留下来的算法已经不多,这其中包括MD2、MD4、MD5、SHA、SHA-1/256/383/512等。
常用的摘要算法主要有MD5和SHA1。MD5的输出结果为16字节,sha1的输出结果为20字节。
在公钥密码系统中,加密和解密使用的是不同的密钥,这两个密钥之间存在着相互依存关系:即用其中任一个密钥加密的信息只能用另一个密钥进行解密。这使得通信双方无需事先交换密钥就可进行保密通信。其中加密密钥和算法是对外公开的,人人都可以通过这个密钥加密文件然后发给收信者,这个加密密钥又称为公钥;而收信者收到加密文件后,它可以使用他的解密密钥解密,这个密钥是由他自己私人掌管的,并不需要分发,因此又成称为私钥,这就解决了密钥分发的问题。
主要的公钥算法有:RSA、DSA、DH和ECC。
Openssl中大量用到了回调函数。回调函数一般定义在数据结构中,是一个函数指针。通过回调函数,客户可以自行编写函数,让openssl函数来调用它,即用户调用openssl提供的函数,openssl函数再回调用户提供的函数。这样方便了用户对openssl函数操作的控制。在openssl实现函数中,它一般会实现一个默认的函数来进行处理,如果用户不设置回调函数,则采用它默认的函数。
{% endtabs %}
命令详解
help
$ openssl help (所有命令帮助)
.....
$ openssl help dgst (列出命令dgst帮助)
.....
$ openssl help list (列出命令list帮助) 等同于 openssl list -help
.....
标准命令(Standard commands)
$ openssl list -commands (列出标准命令)
......
- asn1parse
asn1parse是一个有效的诊断工具,可以解析ASN.1结构。也可用来从ASN.1格式的数据中提取数据。 - ca
ca是一个极小的CA应用程序。它可被用于签名各种证书请求及生成CRLs,它也包含了一个文本数据库,其中记录了已经发布的证书以及这些证书的状态。 - ciphers
显示支持的加密套件。 - cms
该命令处理S/MIME v3.1邮件。可以用它对S/MIME消息进行加密、解密、签名、验证签名、压缩以及解压缩等操作。 - crl
crl命令用于处里PME或DER格式的CRL文件(证书吊销列表 (Certificate Revocation List ,简称: CRL) 是 PKI 系统中的一个结构化数据文件) - crl2pkcs7
本命令根据CRL或证书来生成pkcs#7消息。 - dgst
dgst用于数据摘要。
echo -n "123456" | openssl dgst -md5 # 输出md5值
echo -n "123456" | openssl dgst -sha1 # 输出sha1值
echo -n '123456' > a.txt
openssl dgst -md5 a.txt # 输出文件md5值与上例相同
- dhparam
生成和管理Diffie-Hellman参数。被genpkey和pkeyparam取代 - dsa
DSA数据管理。处理DSA密钥、格式转换和打印信息,用于数字签名 - dsaparam
DSA参数生成与管理。用于生成和操作dsa证书参数,用于数字签名,被genpkey和pkeyparam取代 - ec
EC(椭圆曲线)密钥处理,用于数字签名和加密 - ecparam
EC参数的操作和生成,产生ECC密钥对。用于数字签名和加密 - enc
加密和解密
对称加密算法工具。它能够运用块或者流算法对数据加/解密。还能够把加密/接密,还可以把结果进行base64编码。
openssl enc -des3 -e -in a.txt -out b.txt
engine
引擎(loadble模块)信息和操纵。errstr
本命令用于查询错误代码。
openssl errstr 02001002
- gendsa
gendsa根据DSA密钥参数生成DSA密钥,dsa密钥参数可用dsaparam命令生成。 - genpkey
生成私钥或参数。
鼓励使用genpkey,因为可以使用额外的算法选项和ENGINE提供的算法。
# 生成RSA私钥
$openssl genpkey -out rsa_pri.key -outform PEM -pass pass:123456 -aes-128-cbc \
-algorithm RSA -pkeyopt rsa_keygen_bits:1024 -text
# 这种方式生成的RSA私钥 不仅代用 私钥和大数,还代用公钥,以及其它信息,以用于快速计算。
- genrsa
生成RSA密钥。 - help
帮助 - list
列出命令 - nseq
创建或检查netscape证书序列,多证书与netscape证书序列间相互转化 - ocsp
在线证书状态协议实用程序。 - passwd
生成散列密码。生成各种口令密文 - pkcs12
PKCS12数据管理。工具,用于生成和分析pkcs12文件 - pkcs7
PKCS7加密消息语法,各种消息存放的格式标准;用于处理DER或者PEM格式的pkcs7文件 - pkcs8
私钥转换工具,pkcs8格式 - pkey
pkey命令处理公钥或私钥。它们可以在各种形式之间进行转换,并将其结构打印出来。
//由私钥生成公钥
$openssl pkey -in rsa_pri.key -inform PEM -passin pass:123456 -out rsa_pub.key -outform PEM -pubout -text
//私钥改密码
$openssl pkey -in rsa_pri.key -inform PEM -passin pass:123456 -out rsa_change.key -outform PEM -passout pass:456789 -des-cbc -text
//改变公钥格式
$openssl pkey -in rsa_pub.key -inform PEM -out rsa_pub_der.key -outform DER -pubin -pubout -text
-
pkeyparam
- 该命令没有-inform或-outform选项,因为仅支持PEM格式,因为密钥类型由PEM头决定。
pkeyutl
公钥算法加密操作实用程序。pkeyutl命令可用于执行支持的公钥操作.prime
检查一个数是否是素数rand
生成伪随机字节。rehash
为文件创建一个符号连接,并将此符号连接的名称设为文件的hash值,作用是让openssl在证书目录中能够找到证书req
PKCS10 X.509证书签名请求(CSR)管理。
req命令主要创建证书请求(可以新生成私钥),查看证书请求。它可以创建自签名证书,以作为root CA使用。但不能读取证书rsa
RSA密钥管理。处理RSA密钥、格式转换和打印信息rsautl
RSA实用程序用于签名,验证,加密和解密。取而代之的是pkeyutls_client
这将实现一个通用SSL / TLS客户端,可以建立与远程服务器的SSL / TLS透明连接。s_server
这实现了一个通用SSL / TLS服务器,它接受来自远程客户端的SSL / TLS连接。s_time
SSL连接定时器。提供的SSL/TLS性能测试工具,测试服务sess_id
SSL会话数据管理。SSL/TLS协议的session处理工具smime
S / MIME邮件处理。处理S/MIME邮件,加密、解密、签名和验证speed
算法速度测量。,调整测试库的性能spkac
SPKAC打印和生成实用程序srp
secure remote password SRP协议storeutl
这个命令可用于显示从给定uri中获取的内容(根据具体情况在解密之后)。ts
时间戳机构工具(客户端/服务器)verify
X.509证书验证。version
openssl versionx509
X.509证书管理。显示证书信息、转换证书格式、签名证书请求及改变证书信任设置,X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。
摘要算法命令(Message Digest commands)
$ openssl list -digest-commands (列出摘要命令)
......
$ openssl list -digest-algorithms (列出摘要算法)
......
- 所有新应用程序的选择的摘要算法是SHA1。 然而其他摘要算法仍然被广泛使用。
- 在签名时,dgst将根据私钥的ASN.1信息自动确定用于签名的算法(RSA,ECC等)。当验证签名时,它只处理RSA,DSA或ECDSA签名本身,而不是分析相关数据来识别签名者和相关算法,如x.509,CMS和S / MIME的签名者和算法。
- 某些签名算法,特别是ECDSA和DSA需要一个随机数源。
- 仅当单个文件要签名或验证时,才能使用签名和验证选项
- 十六进制签名无法使用openssl进行验证。使用“xxd -r”或类似程序在验证之前将十六进制签名转换为二进制签名。
加解密命令(Cipher commands)
$ openssl list -cipher-commands (列出加解密命令)
......
$ openssl list -cipher-algorithms (列出加解密算法)
......
- 该程序可以通过openssl ciphername或者openssl enc -ciphername 两种方式调用,但是前一种不支持引擎加密.
- 应在配置文件中配置提供全新加密算法的引擎(如提供gost89算法的ccgost引擎)。在命令行中使用-engine选项指定的引擎只能用于由配置文件中指定的OpenSSL内核或其他引擎支持的密码的硬件辅助实现
- 当enc命令列出支持的加密算法时,也列出了配置文件中指定的引擎提供的算法。
- 如果需要,将提示输入密钥以获得密钥。
- 如果从密码派生密钥,则应使用-salt选项,除非您希望与以前版本的OpenSSL和SSLeay兼容。没有-salt选项,可以对密码执行有效的字典攻击,并攻击流密码加密数据。原因是没有slat,相同的密码总是生成相同的加密密钥。当slat被使用时,加密数据的前八个字节被保留给盐:它在加密文件时被随机生成,并且在被解密时从加密文件读取。
- 一些密码没有大的密钥,如果不正确使用,会带来安全隐患。建议初学者在CBC模式下使用强分组密码,如bf或des3。
- 所有块密码通常使用PKCS#5填充也称为标准块填充:这允许执行基本的完整性或密码检查。然而,由于随机数据通过测试的机会优于256中的1,这不是一个非常好的测试。
- 如果禁止填充,则输入数据必须是密码块长度的倍数。
- 所有RC2密码具有相同的密钥和有效的密钥长度。
- Blowfish和RC5算法使用128位密钥。
常用命令总结
# 生成100位随机数,使用base64编码输出
openssl rand -base64 100
# 输出到文件myr.dat
openssl rand –base64 –out myr.dat 100
# 16进制方式输出
openssl rand -hex 10
# 生成md5摘要
echo -n 123456 | openssl dgst -md5 | awk '{printf("%s",md5)}'
# 生成sha1摘要
echo -n 123456 | openssl dgst -sha1 | awk '{printf("%s",sha1)}'
# 对称加密
# 生成16进制加密字符串
echo -n "我们是害虫,正义的来福灵快来把我杀死!"|openssl enc -e -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 | od -tx1 | awk '{for(i=2;i<=NF;i++){printf("%s",);}}'
# 解密16进制加密字符串
echo -n "6556492b1fbfd723fb2af8dc32fa0b2105007adde27f96d257abc45b9a1ddaee9fa8999029e756cfd1cabf24c941ab7ce6925f1ff7a7123db9921f9d596625a7"| sed 's/\(..\)/\\\\x\1/g' | xargs echo -e -n | openssl enc -d -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001
# 生成base64编码加密字符串
echo -n "我们是害虫,正义的来福灵快来把我杀死!"|openssl enc -e -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 -a -A
# 解密base64字符串
echo -n "ZVZJKx+/1yP7KvjcMvoLIQUAet3if5bSV6vEW5od2u6fqJmQKedWz9HKvyTJQat85pJfH/enEj25kh+dWWYlpw=="|openssl enc -d -aes-128-ecb -K 226a89e66d0dcc79c9673150fa176001 -a -A
# 以上aes-128-ecb为加解密算法,-K参数表示加密秘钥,加密和解密方需妥善保存
# 非对称,使用公钥加密,私钥解密
# 生成私钥
openssl genpkey -out cxl_rsa_pri.key -outform PEM -pass pass:whyme -aes-128-cbc -algorithm RSA -pkeyopt rsa_keygen_bits:1024 -text
# 用私钥生成公钥
openssl pkey -in cxl_rsa_pri.key -inform PEM -passin pass:whyme -out cxl_rsa_pub.key -outform PEM -pubout -text
# 用公钥加密,输出base64编码
echo -n '123456' | openssl pkeyutl -encrypt -inkey cxl_rsa_pub.key -keyform PEM -pubin | base64 -w0
# 用私钥解密
echo -n 'QmjiDoh/j+dtdxuZ0BUlrRTHbZFCzb43ZnM+cbpT93JnRQa64MrTLrAj50O1EM/voM9KPgvQfuiIhQbwKdeDXV66ZmlbsXfhc0PW2xMDCqJaR77E2N8yyAFWx4Z698zCqWx86svgscpQp62dwX/9P0+e1za2lbFCe8h0wv2ZQcE=' | base64 -d | openssl pkeyutl -decrypt -inkey cxl_rsa_pri.key -passin pass:whyme
# 由用户侧传过来的数据都是加密后的数据,没有私钥无法查看原始数据
# 使用私钥签名
echo -n '123456' | openssl pkeyutl -sign -inkey cxl_rsa_pri.key -keyform PEM -passin pass:whyme | base64 -w0
# 使用公钥验证签名
echo -n '123456' > data.txt
echo -n 'DPBPRL/DTmR8llgjF16U1NDtZTgLLYBaqq2IP/wwWilEbJDpKCVb7mx82EwtSi6GAisx4TzL9U/O6bpyJeVFrCMhLkKo3Lhs2hzQMBKi42CcsTHcEiCH6o6eOI+1ZpfdDXDFz7/IdQJdek0oXx6cZPuWlWqiq2bEmZK2T9zbFBE=' | base64 -d > sig
openssl pkeyutl -verify -inkey cxl_rsa_pub.key -keyform PEM -pubin -in data.txt -sigfile sig
# 服务器发给客户端的数据由客户端验证签名,保证数据没有篡改过
# 证书
openssl version -a
#查看版本和配置文件位置,生成证书可以使用配置文件中的相关配置,本例中不使用这种方式,各位可以研究一下
-nodes :如果指定-newkey自动生成秘钥,那么-nodes选项说明生成的秘钥不需要加密,即不需要输入passphase.
-batch :指定非交互模式,直接读取config文件配置参数,或者使用默认参数值
# 生成证书,可以在生成证书的时候生成私钥,也可以指定私钥文件生成证书,如果都不指定,会自动生成私钥文件
# 生成自签名证书,证书名cxl-req.crt,不指定私钥,私钥名为配置文件中名称或缺省privkey.pem
openssl req -x509 -newkey rsa:1024 -out cxl-req.crt
# 指定私钥密码
openssl req -x509 -newkey rsa:1024 -out cxl-req.crt -passout pass:123456
# 指定证书参数
openssl req -x509 -newkey rsa:1024 -out cxl-req.crt -passout pass:123456 -subj /C=CN/ST=北京市/L=城市名/OU=组织名/O=公司名/CN=whatthis/emailAddress=test@company.com
# 查看证书内容
openssl x509 -in cxl-req.crt -noout -text
openssl x509 -in cxl-req.crt -noout -subject
openssl x509 -in cxl-req.crt -noout -pubkey
# 指定私钥名称 cxl-req-pri.pem
openssl req -x509 -newkey rsa:1024 -out cxl-req.crt -keyout cxl-req-pri.pem -outform PEM -passout pass:123456 -subj /C=CN/ST=provincename/L=cityname/OU=organizationname/O=companyname/CN=whatthis/emailAddress=test@company.com
# 使用密钥生成证书
openssl req -new -x509 -key cxl-req-pri.pem -outform PEM -passin pass:123456 -out cxl-req111.crt -subj /C=CN/ST=provincename/L=cityname/OU=organizationname/O=companyname/CN=whatthis/emailAddress=test@company.com
# 查看证书
openssl x509 -in cxl-req111.crt -noout -text