OpenSSL笔记

OpenSSL 笔记

对称加密(可以加解密文件)

用密码加密,并该密码解密

工具:openssl enc, gpg
支持的算法:3des, aes, blowfish, towfish

enc命令:
加密:openssl enc -e -des3 -a -salt -in somefile -out somefile.ciphertext

$ openssl enc -e -des3 -a -salt -in somefile -out somefile.ciphertext
enter des-ede3-cbc encryption password:

$ cat somefile.ciphertext
U2FsdGVkX1/7g310phi4Qiw6ykWbQzreMpJ2tI2EqJoNxUsNaAvOrairvqRgGB3x
1j+AYji2wZ0=

解密:openssl enc -d -des3 -a -salt -out somefile -in somefile.ciphertext

$ openssl enc -d -des3 -a -salt -out somefile_decode -in somefile.ciphertext
enter des-ede3-cbc decryption password:

$ cat somefile_decode
Text that needs to be encrypted.

单向加密

工具:openssl dgst, md5sum, sha1sum, sha224sum, …

dgst命令(摘要命令):

openssl dgst
常用选项有:
[-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1] :指定一种摘要算法
-out filename:将摘要的内容保存到指定文件中

openssl dgst -md5 /PATH/TO/SOMEFILE

[root@promote ~]# md5sum fstab
c58fef6dca558db2e6122bdf12f66aba  fstab
[root@promote ~]# openssl dgst -md5 fstab
MD5(fstab)= c58fef6dca558db2e6122bdf12f66aba

生成用户密码:
工具:passwd, openssl passwd

openssl passwd [-crypt] [-1] [-apr1] [-salt string] [-in file] [-stdin] [-noverify] [-quiet] [-table] {password}
常用选项有:

-1:使用md5加密算法
-salt string:加入随机数,最多8位随机数
-in file:对输入的文件内容进行加密
-stdion:对标准输入的内容进行加密

openssl passwd -1 -salt SALT

[root@promote ~]# openssl passwd -1 -salt 12345678
Password: 
$1$12345678$2MUF23c1xwXhNSpW3dupd.

生成随机数:
工具:openssl rand

生成随机数需要用到的标准命令为 rand ,用法如下:
openssl rand [-out file] [-rand file(s)] [-base64] [-hex] num
常用选项有:
-out file:将生成的随机数保存至指定文件中
-base64:使用base64 编码格式
-hex:使用16进制编码格式

openssl rand -hex NUM
openssl rand -base NUM

[root@promote ~]# openssl rand -base64 12
0iMFITFdgsHDsKLA
[root@promote ~]# openssl rand -hex 12
6e02d827b1944dfe66e18b93

生成密钥对

生成私钥

首先需要先使用 genrsa 标准命令生成私钥,然后再使用 rsa 标准命令从私钥中提取公钥。
genrsa 的用法如下:

openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [-f4] [-3] [-rand file(s)] [-engine id] [numbits]
常用选项:
-out filename:将生成的私钥保存至指定的文件中
-des|-des3|-idea:不同的加密算法
numbits:指定生成私钥的大小,默认是2048

一般情况下秘钥文件的权限一定要控制好,只能自己读写,因此可以使用 umask 命令设置生成的私钥权限,示例如下:

# wwb @ wwb-PC in ~/tmp/test [11:24:24]
$ (umask 066;openssl genrsa -out ./my.key)
Generating RSA private key, 2048 bit long modulus
....................................................+++++
......+++++
e is 65537 (0x10001)

# wwb @ wwb-PC in ~/tmp/test [11:24:38]
$ ll
total 8
-rw-------  1 wwb  staff   1.6K 11  6 11:24 my.key

生成公钥

公钥是由私钥计算出来的

ras 的用法如下:

openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin arg] 
			[-out filename] [-passout arg] [-sgckey] [-des] [-des3] [-idea] [-text] [-noout] 			 [-modulus] [-check] [-pubin] [-pubout] [-engine id]
常用选项:
-in filename:指明私钥文件
-pubout:根据私钥提取出公钥 

生成公钥的示例如下:

# wwb @ wwb-PC in ~/tmp/test [11:28:01]
$ openssl rsa -in key.pem -pubout -out pubkey.pem
writing RSA key

# wwb @ wwb-PC in ~/tmp/test [11:28:10]
$ cat pubkey.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk2J8oZm9opjZDNrAVe6I
gTN4ZSTJFi1lYuZ4+dKhW9M/JFjdCwITaGcdoa8icJVAbh43ci9d8XeBPksvJ5ZT
09z4RDg3A6gSVwJf+lm0oZfQQQVayU5pRAjt88hX4TFrL0AN6DjwVU21HcTXGgnB
ycxW4Pxxe5hXCdyDJWbG3Tg9dVKWYTxubhpFM/a7v3S1iGIU4IRW3u8aS/xmPuh+
jkcPq73INyG3dle4rlVQ3zDa0IshPbEz9I95OoFOg8QCbI2qqdMBSgjg2glbWUOU
n2zbKiiaozrCE+doPEpB4Hh6ciAMt0psK6jFAdZGfHNQkW4YUqBF12oDR9nyEIv/
rQIDAQAB
-----END PUBLIC KEY-----

创建证书

创建一个私钥并生成一个证书请求

 openssl genrsa -out key.pem 2048
 openssl req -new -key key.pem -out req.pem

或者用另一种方式(与上面效果是一样的):

openssl req -newkey rsa:2048 -keyout key.pem -out req.pem

同时生成一个私钥和一个自签名根证书:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem

生成一个自签名根证书:

#使用CSR创建自签名证书
openssl x509 -req -days 365 -in request.csr -signkey private.key -out web.crt

#不生成中间文件CSR,直接生成自签名证书
openssl req -new -x509 -days 365 -key private.key -out web.crt

#验证证书内容
openssl x509 -text -in web.crt -noout

有关自签名证书和TLS如何工作的,可以参考这里

使用私钥签名

使用私钥签名数据:

 openssl rsautl -sign -in file -inkey key.pem -out sig

恢复被签名的数据

openssl rsautl -verify -in sig -inkey key.pem

# 输出签名时file的内容。
# 更像是使用私钥将file加密,保存在sig中,sig就包含了file中的所有原始数据,而不是对file的hash签名。此处的inkey是私钥,而不是使用公钥校验。

X.509命令使用

显示证书内容:

 openssl x509 -in cert.pem -noout -text

显示证书的序列号:

 openssl x509 -in cert.pem -noout -serial

Display the certificate subject name:

 openssl x509 -in cert.pem -noout -subject

Display the certificate subject name in RFC2253 form:

 openssl x509 -in cert.pem -noout -subject -nameopt RFC2253

Display the certificate subject name in oneline form on a terminal supporting UTF8:

 openssl x509 -in cert.pem -noout -subject -nameopt oneline,-esc_msb

Display the certificate SHA1 fingerprint:

 openssl x509 -sha1 -in cert.pem -noout -fingerprint

Convert a certificate from PEM to DER format:

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

Convert a certificate to a certificate request:

 openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem

Convert a certificate request into a self signed certificate using extensions for a CA:

 openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca \
        -signkey key.pem -out cacert.pem

Sign a certificate request using the CA certificate above and add user certificate extensions:

 openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr \
        -CA cacert.pem -CAkey key.pem -CAcreateserial

Set a certificate to be trusted for SSL client use and change set its alias to “Steve’s Class 1 CA”

 openssl x509 -in cert.pem -addtrust clientAuth \
        -setalias "Steve's Class 1 CA" -out trust.pem

私钥与证书的存储格式

私钥和证书的存储格式有很多种,我们可能经常需要在各种格式中转换,常用格式如下:

Binary(DER)格式证书

包含X.509证书原始格式,使用DER ASN.1编码。

ASCII(PEM)格式证书

使用base64编码的DER格式证书,以-----BEGIN CERTIFICATE-----作为文件第一行内容,-----END CERTIFICATE-----作为文件最后一行内容

Binary(DER)格式密钥

包含密钥原始内容,使用DER ASN.1编码。

ASCII(PEM)格式密钥

包含使用base64编码的DER格式密钥,有时会包含额外信息,例如保护私钥的密码。

PKCS#7格式证书

用来传输被签名或者加密的数据的复杂格式,常见扩展名有p7bp7c,可包含整个证书链,Java的keytool工具支持这种格式。

PKCS#12(PFX)格式的密钥和证书

一种用来存储和保存密钥及证书的复杂格式,常见扩展名有p12pfx,微软的产品经常会使用到。

PEM与DER格式之间的转换:

#证书 PEM格式转DER
openssl x509 -inform PEM -in web.crt -outform DER -out web.der

#证书 DER格式转PEM
openssl x509 -inform DER -in web.der -outform PEM -out web.crt

#密钥 PEM格式转DER,替换rsa为你使用的密钥算法即可
openssl rsa -inform PEM -in private.key -outform DER -out private.der

#密钥 DER格式转PEM,替换rsa为你使用的密钥算法即可
openssl rsa -inform DER -in private.der -outform PEM -out private.key

PEM与PKCS#7证书格式之间的转换:

  1. 将PEM格式的证书(web.crt),中间证书(web-intermediate.crt)转换为PKCS#7文件。
openssl crl2pkcs7 -nocrl -out saved.p7b -certfile web.crt -certfile web-intermediate.crt
  1. 将PKCS#7转换为PEM格式,由于结果都存放在一个文件中,我们需要将combined.pem文件里的内容手动分离出来。
openssl pkcs7 -in saved.p7b -print_certs -out combined.pem

PEM与PKCS#12格式之间的转换:

  1. 将PEM格式的私钥(private.key),证书(web.crt),中间证书(web-intermediate.crt)转换为PKCS#12文件。
openssl pkcs12 -export -name "Certificate Name" -out saved.p12 -inkey private.key -in web.crt -certifile web-intermediate.crt
  1. 将PKCS#12转换为PEM格式就不这么直接了,因为转换的结果放在一个文件里面,所以我们必须手动的将combined.pem里的内容分离。
openssl pkcs12 -in saved.p12 -out combined.pem -nodes

TLS配置

在发布TLS时,第一步就是加密套件的选择,所有使用OpenSSL的软件都要使用其提供的套件配置机制。例如nginx中配置加密套件:

ssl_ciphers  HIGH:!aNULL:!MD5

其中HIGH:!aNULL:!MD5是加密套件的关键字和相关操作符的组合来选择一组加密套件。

以下是四类操作符的说明。

  1. :与``即冒号与空格
    通过这两个操作符都可添加新的加密套件到结果列表中,例如RSA:AES 或者RSA AES
  2. -
    与关键字组合从现有列表中移除指定的加密套件,被移除的套件可以被后续的关键字再次引入。例如RSA-DES
  3. !
    永久移除关键字指定的加密套件。例如!MD5
  4. +
    通过制定多个关键字来组合起来筛选加密套件。例如RSA+AES

有关于所有可用的关键字,可以参考这里

我们可以使用以下命令来验证关键字与操作符组合选择的加密套件:

#"RSA:AES"可换乘其他组合
openssl ciphers -v "RSA:AES"

测量指定加密算法或者摘要算法速度时(测量的结果只是大概,如果想多线程测试,可查询speed的选项),我们可以使用以下命令:

#aes可替换为其他值
openssl speed aes

创建私有CA

  1. 创建CA配置信息。

    对于创建CA这种复杂的操作,我们可以创建一个配置文件(root_ca.conf)来简化我们的操作。

​ 一个配置文件可以分为很多节,每一节都以**[section_name]**作为起始行,直到碰到另一节的起始行或者到文件结尾,则该节结束。每节的名称只能是字母数字下划线。

​ 配置文件中的第一节是特殊的,被认为是**[default]**节,通常是不命令的,当碰到另一个命名的节时,该默认节即结束。当查询一个名字时,先从命名的节中查询,最后再查询默认节。

​ 环境变量被映射到名为ENV的节中。

​ 配置文件中的注释以**#**开头。

​ 配置文件中的每一节都包含有键值对,形式如name=value. 的可选字符集是**[alphanumeric . , ; _], 对应着=后面的所有字符,去除头尾空格。中可以包含变量展开,形式是 n a m e ∗ ∗ 或 者 ∗ ∗ name**或者** name{name},这将会使用在本节中查找到的name对应的值进行替换;如果想要使用其他节中的值进行替换,可以使用 s e c t i o n : : n a m e ∗ ∗ 或 者 ∗ ∗ section::name**或者** section::name{section::name};如果想要使用环境变量进行替换可以使用形式$ENV::name**。如果value最后一个字符是****,则value是可以跨行的,同时也可以包含任意转义字符。

​ 以下是配置信息的示例。

#基本的CA配置信息
[default]
name=root_ca
domain_suffix=example.com
aia_url=http://$name.$domain_suffix/$name.crt
crl_url=http://$name.$domain_suffix/$name.crl
ocsp_url=http://ocsp.$name.$domain_suffix:9080
default_ca=ca_default
name_opt=utf8,esc_ctrl,multiline,lname,align

#供req节中键distinguished_name使用
[ca_dn]
countryName="GB"
organizationName="Example"
commonName="Root CA"

#控制CA操作的配置信息,可通过man ca命令来查看所有可选参数
[ca_default]
home=.
database=$home/db/index
serial=$home/db/serial
crlnumber=$home/db/crlnumber
certificate=$home/$name.crt
private_key=$home/private/$name.key
RANDFILE=$home/private/random
new_certs_dir=$home/certs
unique_subject=no
copy_extensions=none
default_days=3650
default_crl_days=365
default_md=sha256
#指定所有从本CA签发的证书的策略,策略内容在policy_c_o_match节中
policy=policy_c_o_match

#策略要求被签发证书的countryName和organizationName必须匹配根CA
[policy_c_o_match]
countryName=match
stateOrProvinceName=optional
organizationName=match
organizationalUnitName=optional
commonName=supplied
emailAddress=optional

#req命令的配置信息,仅被使用一次来创建自签名根证书
[req]
default_bits=4096
encypt_key=yes
default_md=sha256
utf8=yes
string_mask=utf8only
prompt=no
distinguished_name=ca_dn
req_extensions=ca_ext

[ca_ext]
#标识证书是CA
basicConstraints=critical,CA:true
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash

#由根CA签发的证书的配置信息
[sub_ca_ext]
authorityInfoAccess=@issuer_info
authorityKeyIdentifier=keyid:always
#CA:true表示创建的证书是CA,pathlen:0表示由CA签发的证书创建的下级证书不能是CA
basicConstraints=critical,CA:true,pathlen:0
crlDistributionPoints=@crl_info
#TLS客户端和服务器
extendedKeyUsage=clientAuth,serverAuth
keyUsage=critical,keyCertSign,cRLSign
nameConstraints=@name_constraints
subjectKeyIdentifier=hash

[crl_info]
URI.0=$crl_url

[issuer_info]
caIssuers;URI.0=$aia_url
OCSP;URI.0=$ocsp_url

[name_constraints]
#限定域名
permitted;DNS.0=example.com
permitted;DNS.1=example.org
#以下两个限制来源于 CA/Browser Forum‘s Baseline Requirements
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

#用于OCSP报文签名的证书拓展项,为了运行OCSP服务器,我们创建一个特殊证书并且代理OCSP签名。
[ocsp_ext]
authorityKeyIdentifier=keyid:always
#该证书不是CA
basicConstraints=critical,CA:false
extendedKeyUsage=OCSPSigning
keyUsage=critical,digitalSignature
subjectKeyIdentifier=hash

目前对于nameConstraints的支持还不是很全面,详情可以参照这里这里

  1. 创建CA目录
mkdir root_ca
cd root_ca
mkdir certs db private
chmod 700 private
touch db/index
#如果创建共用distinguished_name的CA证书时,每次都要重新生成serial
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber

以下是各个目录作用的说明:

  • certs/
    存储生成的证书。
  • db/
    存放证书数据库(index),证书和CRL的序列号,或者openssl创建的额外文件。
  • private/
    CA和OCSP的私钥。
  1. 创建根CA
    第一步创建私钥和CSR。
openssl req -new -config root_ca.conf -out root_ca.csr -keyout private/root_ca.key

第二步创建自签名证书。

openssl ca -selfsign -config root_ca.conf -in root_ca.csr -out root_ca.crt -extensions ca_ext

创建完CA证书后我们会在当前文件夹(root_ca.crt)和certs文件夹内(XXXX.pem)得到一样的证书。我们可以查看db/index得到生成的证书的记录。

 V  270818135219Z       DDBBFB87753B0599CC2C6B26C36017CB    unknown/C=GB/O=Example/CN=Root CA

第一列:状态标识,可选值有V (valid)R (revoked)E(expired)。
第二列:过期日期,格式为(YYMMDDHHMMSSZ)。
第三列:注销日起,如果没有即为空。
第四列:序列号,十六进制。
第五列:文件位置,如果未知值为unknown。
第六列:标识名。

  1. 根CA操作
  • 从CA生成CRL
openssl ca -gencrl -config root_ca.conf -out root_ca.crl
  • 签发证书
    生成的证书存储在certs/存在certs文件夹内,文件名是序列号,你可以通过db/index的标识名来在certs文件夹内查询对应的证书文件。同时你指定的web.crt文件也会被生成。
#sub_ca.csr是你生成证书的请求
openssl ca -config root_ca.conf -in request.csr -out web.crt -extensions sub_ca_ext
  • 撤销证书
    撤销原因可以通过crl_reason来指定,可选值有unspecified、keyCompromise、CACompromise、CACompromise、affiliationChanged、superseded、cessationOfOperation、certificateHold、removeFromCRL
#DDBBFB87753B0599CC2C6B26C36017CB.pem是你要吊销的证书,通过db/index文件来查询。
openssl ca -config root_ca.conf -revoke certs/DDBBFB87753B0599CC2C6B26C36017CB.pem -crl_reason keyCompromise
  1. 创建OCSP签名证书
    第一步为OCSP响应器创建私钥和CSR。
#rsa:2048代表创建2048位的rsa私钥;subj选项对应的值中C代表countryName,O代表organizationName,CN代表commonName。
openssl req -new -newkey rsa:2048 -subj "/C=GB/O=Example/CN=OCSP Root Responder" -keyout private/root_ocsp.key -out root_ocsp.csr

第二步使用根CA签发证书,使用-extensions ocsp_ext来确保正确签发OCSP证书,同时通过days 30调整证书过期时间,越短越好,因为OCSP证书不包含撤销信息,无法被撤销。

openssl ca -config root_ca.conf -in root_ocsp.csr -out root_ocsp.crt -extensions ocsp_ext -days 30

我们可以通过以下命令来测试生成的OCSP证书。

#启动本地的OCSP响应器,一般不要放在根CA所在的机器
openssl ocsp -port 9080 -index db/index -rsigner root_ocsp.crt -rkey private/root_ocsp.key -CA root_ca.crt -text

#验证OCSP响应器操作
openssl ocsp -issuer root_ca.crt -CAfile root_ca.crt -cert root_ocsp.crt -url http://127.0.0.1:9080

验证成功后,会得到类似于以下的内容:

Response verify OK
root_ocsp.crt: good
        This Update: Aug 21 09:37:03 2017 GMT

创建下级CA

  1. 创建下级CA和创建根CA步骤是一样的,我们以根CA的配置文件(sub_ca.conf)为基础,做了以下列出来的修改,注意单词拼写,如果有错误的话对照着错误提示或者下面的示例来更改:
[default]
name=sub_ca
ocsp_url=http://ocsp.$name.$domain_suffix:9081

[ca_dn]
countryName="GB"
organizationName="Example"
commonName="Sub CA"

[ca_default]
default_days=365
default_crl_days=30
#copy代表CSR的extensions会被拷贝到证书中
copy_extensions=copy

新增了server_extclient_ext两个节:

[server_ext]
authorityInfoAccess=@issuer_info
authorityKeyIdentifier=keyid:always
basicConstraints=critical,CA:false
crlDistributionPoints=@crl_info
extendedKeyUsage=clientAuth,serverAuth
keyUsage=critical,digitalSignature,keyEncipherment
subjectKeyIdentifier=hash

[client_ext]
authorityInfoAccess=@issuer_info
authorityKeyIdentifier=keyid:always
basicConstraints=critical,CA:false
crlDistributionPoints=@crl_info
extendedKeyUsage=clientAuth
keyUsage=critical,digitalSignature
subjectKeyIdentifier=hash
  1. 生成下级CA
  • 首先参照根CA创建CA目录。
  • 生成下级CA私钥和CSR
openssl req -new -config sub_ca.conf -out sub_ca.csr -keyout private/sub_ca.key
  • 使用根CA签发下级CA证书
#开关extensions指定root_ca.conf中的sub_ca_ext节来配置下级CA的extensions。注意文件路径。
openssl ca -config root_ca.conf -in sub_ca.csr -out sub_ca.crt -extensions sub_ca_ext
  1. 下级CA的操作
  • 签发服务端证书
    执行以下命令时可能会提示db/index.attr文件找不到,该文件内仅仅包含一条信息unique_subject=no/yes对应着我们在sub_ca.conf文件中的配置,我们可以创建这个文件并将信息输入进去。有关这个错误的介绍可以参照这里
openssl ca -config sub_ca.conf -in server.csr -out server.crt -extensions server_ext
  • 签发客户端证书
openssl ca -config sub_ca.conf -in client.csr -out client.crt -extensions client_ext

参考文章

Openssl原理与实战

OpenSSL 介绍和使用

openssl常用使用方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值