openssl与证书机制

1. openssl加密功能

openssl 是一个密码工具集,可以完成对称加密,非对称加密,生成摘要,解密。并且包含多种密码算法。

1.1 对称加密

enc表示执行加密功能,-e是加密,-d是解密。-aes128是加密算法,除此之外还有-dec3/-cast/-blowfish。-in与-out分别是输入输出文件,在不同功能下含义不同。

openssl enc -e -aes128 -in $FileName -out $EncryptFile
openssl enc -d -aes128 -in $EncryptFile -out $FileName

1.2 生成摘要

dgst表示生成摘要,-md5表示摘要生成算法。

openssl dgst -md5 $FileName

还可以直接使用md5sum生成MD5码。除此之外还有sha1sum, sha224sum, sha256sum等等。

md5sum $FileName >> $MD5File
md5sum -c $MD5File

md5sum用于生成文件的digest(摘要)。-c用于检查MD5码是否正确。其中文件名已经包含在$MD5File中了,所以不需要特别给出。

1.3 生成文件签名

数字签名是摘要+非对称加密两个功能的整合。

openssl dgst -md5 -out $SignFile -sign $PrivateKey $FileName

1.4 验证签名文件

验证签名可以使用公钥也可以使用私钥。因为公钥可以从私钥中生成,所以使用私钥验证无非多了一步,先生成公钥再去验证。

openssl dgst -md5 -prverify $PrivateKey -signature $SignFile $FileName
openssl dgst -md5 -prverify $PublicKey -signature $SignFile $FileName

1.5 生成非对称秘钥

与keygen不同,openssl秘钥的生成过程分为两步,首先生成私钥,然后从私钥中产生公钥。genrsa表示生成私钥。-out是输出文件地址。4096是私钥长度。rsa表示提取公钥,-pubout表示从私钥中提取。

openssl genrsa -out cert.key 4096
openssl rsa -pubout -in cert.key -out cert.key.pub

ssh-keygen也是对称秘钥生成工具。在git配置中经常使用。-t是指定秘钥生成算法,-C是公钥的注释内容,方便之后使用时了解秘钥的使用目的。ssh-keygen会将公钥与私钥同步生成,并默认存储在/root/.ssh/id_rsa与id_rsa.pub文件中。

ssh-keygen -t rsa -C "comment"

1.6 为私钥添加/删除保护口令

添加保护口令之后在使用私钥解密或者签名的时候都需要输入口令。

openssl rsa -des3 -in $unencrypt_key -out $encrypt_key  #添加保护口令
openssl rsa -in $encrypt_key  -out $unencrypt_key       #删除保护口令

1.7 非对称加密

对于openssl,使用私钥加密称为签名。openssl的加密都是使用公钥加密。即使输入的是私钥,也是先生成公钥再去加密。所以解密的时候必须使用私钥,公钥是不能解密的。公钥解密称为验证签名。

openssl rsautl -encrypt -in $PlainTXT -inkey $PrivateKey  -out $EncryptTXT              # 虽然输入的私钥,但是实际也是先生成公钥再加密
openssl rsautl -encrypt -in $PlainTXT -inkey $PublicKey -pubin -out $EncryptTXT         # 如果inkey是公钥,需要特别输入-pubin参数,表示使用公钥
openssl rsautl -decrypt -in $EncryptTXT -inkey $PrivateKey  -out $PlainTXT              # 解密必须是私钥,无论使用以上哪一种加密命令!

1.8 非对称签名

使用私钥加密就是签名。验证签名可以使用私钥也可以使用公钥,但是本质都是用公钥解密。

openssl rsautl -sign -in $PlainTXT -inkey $PrivateKey  -out $EncryptTXT                 # 签名必须是私钥
openssl rsautl -verify -in $EncryptTXT -inkey $PrivateKey -out $PlainTXT
openssl rsautl -verify -in $EncryptTXT -inkey $PublicKey -pubin -out $PlainTXT          # 使用公钥解密必须输入-pubin标记

1.9 生成随机数

rand表示生成随机数,10表示10个字节的长度。-base64表示以base64编码输出,也可以使用-hex表示以16进制输出。

openssl rand -base64 10

1.10 生成密码

-crypt表示生成满足crypt标准的密码

openssl passwd -crypt 

2. 创建CA与申请证书

证书是什么?详细内容参考数字签名是什么。简单来说数字证书是依靠第三发认证机构(CA)签发的一个文件,用于证明公钥是属于某个机构!下文讲解如何使用openssl建立一个认证机构,并签发证书。

在上文中我们说openssl是一个加解密工具。那只是openssl的一部分功能,openssl同时也可用于建立一个认证机构,只不过是无人信任的认证机构。建立认证机构需要以下步骤:

  1. 配置openssl的证书管理目录
  2. 生成认证机构(CA)的私钥
  3. 使用私钥自签发证书作为根证书
  4. 生成证书签署请求文件
  5. 签发证书
  6. 认证证书
  7. 吊销证书

2.1 配置openssl的证书管理目录

首先需要解释openssl证书管理目录的内容。下面是一个证书目录样例,根目录地址是/etc/pki/CA

/etc/pki/CA                     # 证书管理目录
├── cacert.pem                  # 自签名证书
├── certs                       # 签发证书存储目录
│   └── cert.crt                # 签发证书
├── crl                         # 吊销证书目录
│   └── ca.crl                  # 吊销证书列表文件
├── crlnumber                   # 吊销证书编号
├── crlnumber.old               # crlnumber的备份文件
├── index.txt                   # 签发证书的文本数据库,包含签发的证书编号,证书信息(地域,公司,用户名,邮箱)
├── index.txt.attr              # 签发证书属性列表,openssl自生成,功能不清楚
├── index.txt.attr.old          # index.txt.attr备份文件
├── index.txt.old               # index.txt备份文件
├── newcerts                    # 签发证书存储目录
│   ├── 01.pem                  # 签发证书
│   └── 02.pem
├── private                     # 私钥存储目录
│   └── cakey.pem               # 私钥
├── serial                      # 当前证书编号
└── serial.old                  # serial的备份

# 特别注意newcerts与certs是对应的。不同之处是newcerts的证书是openssl自己生成,而certs是用户指定输出的。
# newcerts中的证书通过证书编号命名,方便管理。但是内容和certs中对应的文件是完全相同的。

我们要做的第一件事是修改配置文件(/etc/pki/tls/openssl.cnf),将配置文件中的dir项的内容修改为/etc/pki/CA(用户可以自己设定证书根目录)。然后在空的根目录中建立certs,crl,newcerts,private四个文件夹与index.txt、serial两个空文件。在serial中写入01,表示之后签发的证书编号从01开始。

目前我们还没有上面文件目录中那么多文件,后面会一步步生成。但是应当说明证书认证的多种文件,列举如下:

  • cer/der/crt,这些都是证书文件,基于X509协议生成。
  • key,私钥文件
  • csr,certificate signature request,证书签名请求文件
  • pem,openssl使用base64编码的文件。只是表示文件编码格式,私钥,公钥,证书,证书请求都可以使用这种文件类型。具体的功能会在文件内容中标识。
  • crl,certificate revocation list,证书吊销列表。这个文件记录了当前被吊销的证书信息。
  • jks,java key store,java的keytools证书管理工具支持的证书私钥格式。
  • pfx,基于PKCS协议生成的证书,本质是X509证书加上对应的私钥。常用于私钥的存储管理。

2.2 生成认证机构(CA)的私钥

openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096

这一步是生成认证机构自己使用的私钥。私钥和公钥都可以加密,但是目的不同。公钥加密的目的是为了让信息保密,确保只有私钥持有者打开。私钥加密不具备保密功能,因为每个人都可以拿到对应的公钥。但是私钥加密可以确认加密者的身份,就像是指纹和签名一样,可以让别人知道谁加密了。

2.3 使用私钥自签发证书作为根证书

openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem  -out /etc/pki/CA/cacert.pem -days 365

req表示证书功能,-new表示新生成一个证书,-x509表示基于x509协议生成一个自签发证书。-key是指定机构私钥的文件地址。-out是输出文件地址。-days是证书有效期。

自签发证书就是我为自己认证,表示其中的信息(地域,公司,个人,email)都是我自己的。这个证书会作为之后签发的证书的根证书。只要用户相信这个根证书,自然也就相信由根证书签发的一系列证书。

2.4 生成证书签署请求文件

openssl genrsa -out user.key 4096
openssl req -new -key user.key -out user.csr -days 365

这一步不是认证机构需要完成,而是向认证机构请求认证的用户来完成。用户也需要生成自己的私钥,然后用这个私钥生成一个证书签署请求文件(csr,certificate signature request)。csr文件包含用户的信息与公钥。csr并不是证书,是为了获取证书的准备材料。因为用户没有公信力,需要让认证机构来认证自己的信息是正确的。(证明我是我)

2.5 签发证书

openssl ca -in user.csr -out /etc/pki/CA/certs/user.crt -days 365

ca是证书认证功能,-in是证书签署请求文件路径,-out是证书的输出路径。-days是证书有效期。

将csr文件以安全的途径递交给认证机构之后,认证机构就可以签发证书。在认证过程中认证机构会比对自签发证书与csr文件的地域信息(国家country与省份province)。如果这两个信息不同,会拒绝签发证书。这就像美国政府不能管理中国人。

完成证书签发之后可以通过命令查询证书信息。-noout表示不输出证书内容,-serial -dates -subject分别表示展示证书编号,日期,用户信息。

openssl x509 -in /etc/pki/CA/certs/user.crt -noout -serial -dates -subject

我们会发现/etc/pki/CA/serial中编号加一,/etc/pki/CA/newscerts文件夹中出现了01.pem文件,这是openssl存储的签发证书。我们发给用户的证书存储在/etc/pki/CA/certs中,正如我们在命令中指定的那样。index.txt文件中也添加了刚刚签发的证书信息。

2.6 验证证书

openssl verify -CAfile /etc/pki/CA/cacert.pem /etc/pki/CA/certs/user.crt 

-CAfile是提供CA的根证书,最后的参数是需要验证的证书,如果结果OK表示这个证书是这个CA签发的。

在实际应用中服务器需要完成以下两步完成身份验证。

  1. 确认证书内容正确完整,没有被篡改,CA 签名是正确的,没有被吊销(证书序列号不在 CRL 中)。如果 CA 证书不是根证书,还要继续对 CA 证书进行验证。
  2. 提取证书中的公钥,生成一个随机数,用公钥加密发送给对方。对方解密之后返回,两者一直就可以验证对方可信任。

openssl也提供了证书测试的能力。在测试中,我们先使用自己建立的根证书分别签发了server的证书server.crt与client的证书client.crt。然后打开两个窗口,分别输入以下命令。

# 使用server证书测试单向认证
openssl s_server -accept 10001 -key server.key -cert server.crt 
openssl s_client -connect localhost:10001 -CAfile /etc/pki/CA/cacert.pem
# 使用server证书和客户端证书做双向测试
openssl s_server -accept 10001 -key server.key -cert server.crt -Verify 5
openssl s_client -connect localhost:10001 -cert client.crt -key client.key 

-Verify表示需要客户端提供证书

2.7 吊销证书

如果用户私钥泄露,信息更改就需要吊销证书。证书过期之后也需要吊销证书。用户申请吊销证书,需要提供证书的编号与用户信息。认证机构比对确认之后再吊销。在本例中我们要吊销编号为02的证书,命令如下

openssl ca -revoke /etc/pki/CA/newcerts/02.pem

如果是第一次吊销证书,我们还需要更新crl文件。首先将吊销证书编号写入crlnumber文件,然后更新ca.crl文件。-gencrl是重新生成crl文件。

echo 02 > /etc/pki/CA/crlnumber
openssl ca -gencrl -out /etc/pki/CA/crl/ca.crl

参考资料:

openssl命令详解
OpenSSL之十三:证书和CA指令
自建证书配置HTTPS服务器
SSL/TLS原理详解

你可能感兴趣的:(Linux,openssl,CA,证书)