密钥与证书(OpenSSL使用)
非对称加密体系有两个密钥:公钥、私钥。顾名思义,公钥是公开的,私钥是私有的。用法有两种:一种是公钥加密私钥解密,另一种是私钥加密公钥解密。第一种用法用于加密通信,可以保证只有拥有私钥的人才可以解密。第二种用法用于签名,可以用签名者的公钥解开就说明信息的确是签名者发出。但是用来解密的公钥必须是可信的,所以一般公钥加上签名合在一起组成证书。证书里的签名是用第三方私钥对签名内容的摘要进行加密的结果,这个签名真不真实可以用签名者的公钥来验证。同样,签名者的公钥又需要有更可信的人来签名,这样,就形成了证书链,当然,这个链条的顶端就只能自己给自己签了。所以证书是可以自己发给自己的,自签发的证书也可以称为根证书,一旦被安装在电脑里并设为可信证书,那么这些证书拥有者用私钥签名的证书也就会被信任。如果一个证书的私钥被泄露,那么这个证书就不应该再被信任,它所签发出去的所有证书就应该变得不可信,也就是说证书还有一系列管理上的问题,所以一般证书都由专门的证书管理机构也就是CA来颁发。而操作系统也预装了一些根证书,这些构成了现在的数字证书体系。
非对称加密体系里,并不一定通信双方都要有自己的公钥和私钥,只要有一方有就够了。比如服务器和客户端之间,如果要进行加密通信,服务器会把自己的公钥(证书)发给客户端,只要客户端信任这个公钥(证书),那么客户端就可以用这么公钥加密,服务器用自己的私钥解密,服务器用自己的私钥加密传给客户端,客户端就可以用之前收到的服务器的公钥解密。前面的过程中,如果客户端收到的服务器证书并不是自己信任的证书链中的机构颁发的,一般的程序都会提示是否信任此证书,临时信任的话本次会话可以继续,但下一次还会提示,永久信任的话以后就不再提示。协商阶段服务器发送给客户端的也不一定就是证书,像SSH就是直接发送未经签署的公钥,道理是一样的。不过,有的程序有时候就不一定提示,比如Trunderbird在添加采用SSL加密方式的帐号时,就不会提示从而造成添加账号失败。但是如果已经添加了账号,再修改为SSL传输方式时就会提示。这种情况下如果是把服务器的根证书事先导入客户端,就没有问题了。
OpenSSL是一款开源的密钥及证书生成工具,主要功能有:生成私钥、根据私钥生成公钥或CSR(Certificate Signing Request)文件、根据CSR文件签发证书或用私钥直接生成自签名的证书、直接一步生成私钥和自签名的证书。一般来说,要想获得一个数字证书,需要自己生成密钥对,然后把公钥及相关信息(算法、申请人信息)一起拿到CA进行签名,CSR文件其实就是包含这些信息的一个文件。CA用其私钥对CSR进行签名,就得到了证书。这一过程中,私钥是永远也不需要告诉包含CA在内的任何其他人的,不应该由CA在帮助生成密钥对。公钥也不一定非要签署成证书,在不需面对大众的场合,直接把公钥发给对方也是可以的,所以OpenSSL可以根据私钥生成公钥也可以生成CSR,当然,OpenSSL也可以进行签名。简单来说就是CA的技术活它都能干,就是没有一套管理证书的机制而已。下而是OpenSSL的主要用法:
1.生成私钥
openssl genrsa [args] [numbits](用openssl genrsa –help查看详细参数)这个命令用来生成RSA密钥,openssl还可以gen其他,因为dsa密码的长度限制为1024位,而ecdsa密钥没有被CA机构广泛支持,所以算法虽然多,但用得最多的还是RSA。常用的用法是
openssl genrsa -out private-key.pem 2048
中间还可以加上-aes、-des这些对称加密算法对私钥进行保护,不过就要用-passout参数来提供加密密码,不然就会在控制台输入密码。OpeeSSL采用PEM(Privacy Enhanced Mail)格式证书和密钥,PEM实质上是Base64编码的二进制内容,再加上开始和结束行,这种格式可以把公钥、私钥、证书等保存在一个文件中,在服务器上运用比较方便。
2.生成公钥文件
RSA算法生成的私钥就用RSA算法来生成公钥。一般用法:
openssl rsa -in private-key.pem -pubout -out public-key.pem
注意-pubout参数。因为这个命令实际上是用来校验密钥的,默认情况是输出私钥。
3.生成CSR文件
openssl req [options]
openssl req -new -key private-key.pem -out public.csr
如果私钥是有密码保护的,会要求输入pass phrase通行码,然后会提示输入组织架构信息,并且还会提示“接下来会要求你输入几个字段的内容,如果你想让该字段留空,那么你应该输入一个英文句号后回车,如果只敲了回车,那么某些字段会有默认值,这可能跟你想要的不同,所以需要注意这一点”。这里面只有Common Name这个字段是必须输入的。生成的CSR文件不是明文,不过可以同样用req命令来查看
openssl req -text -in public.csr -noout
因为这个命令不仅仅是生成csr,所以要生成csr的话,前面的-new参数是不可少的。
4.签发证书
openssl x509 -req -days 365 -in public.csr -signkey private-key.pem -out public.crt
其中,x509是证书格式;-days是有效期天数。 可以在req命令里用-x509参数直接生成自签名证书,省去生成csr文件的过程。
openssl req -new -x509 -days 365 -key private-key.pem -out public.crt
既然这样可以,那么再加上-newkey参数,就能生成私钥、生成自签名证书一步到位。
openssl req -new -x509 -newkey rsa:4096 -keyout private-key.pem -out public.crt
5.证书格式及转换
-
PEM 格式 PEM格式通常用于数字证书认证机构(Certificate Authorities,CA),扩展名为.pem, .crt, .cer, and .key。内容为Base64编码的ASCII码文件,有类似”—–BEGIN CERTIFICATE—–” 和 “—–END CERTIFICATE—–“的头尾标记。服务器认证证书,中级认证证书和私钥都可以储存为PEM格式(认证证书其实就是公钥)。Apache和类似的服务器使用PEM格式证书。
-
DER 格式 DER格式与PEM不同之处在于其使用二进制而不是Base64编码的ASCII。扩展名为.der,但也经常使用.cer用作扩展名,所有类型的认证证书和私钥都可以存储为DER格式。Java使其典型使用平台。
-
PKCS#7/P7B 格式 PKCS#7 或 P7B格式通常以Base64的格式存储,扩展名为.p7b 或 .p7c,有类似BEGIN PKCS7—–” 和 “—–END PKCS7—–“的头尾标记。PKCS#7 或 P7B只能存储认证证书或证书路径中的证书(就是存储认证证书链,本级,上级,到根级都存到一个文件中)。不能存储私钥,Windows和Tomcat都支持这种格式。
-
PKCS#12/PFX 格式 PKCS#12 或 PFX格式是以加密的二进制形式存储服务器认证证书,中级认证证书和私钥。扩展名为.pfx 和 .p12,PXF通常用于Windows中导入导出认证证书和私钥。
可以使用OpenSSL命令行工具在不同证书格式之间的转换
PEM to DER
openssl x509 -outform der -in certificate.pem -out certificate.der
PEM to P7B
openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer
PEM to PFX
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
DER to PEM
openssl x509 -inform der -in certificate.cer -out certificate.pem
P7B to PEM
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
PFX to PEM
openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes
PXF转PEM后certificate.cer文件包含认证证书和私钥,需要把它们分开存储才能使用。