openssl 是一个密码工具集,可以完成对称加密,非对称加密,生成摘要,解密。并且包含多种密码算法。
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
dgst表示生成摘要,-md5表示摘要生成算法。
openssl dgst -md5 $FileName
还可以直接使用md5sum生成MD5码。除此之外还有sha1sum, sha224sum, sha256sum等等。
md5sum $FileName >> $MD5File
md5sum -c $MD5File
md5sum用于生成文件的digest(摘要)。-c用于检查MD5码是否正确。其中文件名已经包含在$MD5File中了,所以不需要特别给出。
数字签名是摘要+非对称加密两个功能的整合。
openssl dgst -md5 -out $SignFile -sign $PrivateKey $FileName
验证签名可以使用公钥也可以使用私钥。因为公钥可以从私钥中生成,所以使用私钥验证无非多了一步,先生成公钥再去验证。
openssl dgst -md5 -prverify $PrivateKey -signature $SignFile $FileName
openssl dgst -md5 -prverify $PublicKey -signature $SignFile $FileName
与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"
添加保护口令之后在使用私钥解密或者签名的时候都需要输入口令。
openssl rsa -des3 -in $unencrypt_key -out $encrypt_key #添加保护口令
openssl rsa -in $encrypt_key -out $unencrypt_key #删除保护口令
对于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 # 解密必须是私钥,无论使用以上哪一种加密命令!
使用私钥加密就是签名。验证签名可以使用私钥也可以使用公钥,但是本质都是用公钥解密。
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标记
rand表示生成随机数,10表示10个字节的长度。-base64表示以base64编码输出,也可以使用-hex表示以16进制输出。
openssl rand -base64 10
-crypt表示生成满足crypt标准的密码
openssl passwd -crypt
证书是什么?详细内容参考数字签名是什么。简单来说数字证书是依靠第三发认证机构(CA)签发的一个文件,用于证明公钥是属于某个机构!下文讲解如何使用openssl建立一个认证机构,并签发证书。
在上文中我们说openssl是一个加解密工具。那只是openssl的一部分功能,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开始。
目前我们还没有上面文件目录中那么多文件,后面会一步步生成。但是应当说明证书认证的多种文件,列举如下:
openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096
这一步是生成认证机构自己使用的私钥。私钥和公钥都可以加密,但是目的不同。公钥加密的目的是为了让信息保密,确保只有私钥持有者打开。私钥加密不具备保密功能,因为每个人都可以拿到对应的公钥。但是私钥加密可以确认加密者的身份,就像是指纹和签名一样,可以让别人知道谁加密了。
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)都是我自己的。这个证书会作为之后签发的证书的根证书。只要用户相信这个根证书,自然也就相信由根证书签发的一系列证书。
openssl genrsa -out user.key 4096
openssl req -new -key user.key -out user.csr -days 365
这一步不是认证机构需要完成,而是向认证机构请求认证的用户来完成。用户也需要生成自己的私钥,然后用这个私钥生成一个证书签署请求文件(csr,certificate signature request)。csr文件包含用户的信息与公钥。csr并不是证书,是为了获取证书的准备材料。因为用户没有公信力,需要让认证机构来认证自己的信息是正确的。(证明我是我)
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文件中也添加了刚刚签发的证书信息。
openssl verify -CAfile /etc/pki/CA/cacert.pem /etc/pki/CA/certs/user.crt
-CAfile是提供CA的根证书,最后的参数是需要验证的证书,如果结果OK表示这个证书是这个CA签发的。
在实际应用中服务器需要完成以下两步完成身份验证。
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表示需要客户端提供证书
如果用户私钥泄露,信息更改就需要吊销证书。证书过期之后也需要吊销证书。用户申请吊销证书,需要提供证书的编号与用户信息。认证机构比对确认之后再吊销。在本例中我们要吊销编号为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原理详解