SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。一般的应用都是单向认证,如果 应用场景要求对客户来源做验证也可以实现成双向认证。
为 了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议。SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术。SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证,其主要过程如下:
① 客户端的浏览器向服务器传送客户端 SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息。 ② 服务器向客户端传送 SSL 协议的版本号,加密算法的种类,随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。 ③ 客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的 CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过, 通讯将断开;如果合法性验证通过,将继续进行第四步。 ④ 用户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器。 ⑤ 如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器。 ⑥ 如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的 CA 是否可靠,发行 CA 的公钥能否正确解开客户证书的发行 CA 的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的“预主密 码”,然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。 ⑦ 服务器和客户端用相同的主密码即“通话密码”,一个对称密钥用于 SSL 协议的安全数据通讯的加解密通讯。同时在 SSL 通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。 ⑧ 客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。 ⑨ 服务器向客户端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。 ⑩ SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。
双向认证 SSL 协议的具体过程 ① 浏览器发送一个连接请求给安全服务器。 ② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器。 ③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的 CA 中心所签发的。如果是,就继续执行协议;如果不是,客户浏览器就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。 ④ 接着客户浏览器比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果是一致的,客户浏览器认可这个服务器的合法身份。 ⑤ 服务器要求客户发送客户自己的证书。收到后,服务器验证客户的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得用户的公钥。 ⑥ 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。 ⑦ 服务器从客户发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户的公钥加过密后通知浏览器。 ⑧ 浏览器针对这个密码方案,选择一个通话密钥,接着用服务器的公钥加过密后发送给服务器。 ⑨ 服务器接收到浏览器送过来的消息,用自己的私钥解密,获得通话密钥。 ⑩ 服务器、浏览器接下来的通讯都是用对称密码方案,对称密钥是加过密的。 上面所述的是双向认证 SSL 协议的具体通讯过程,这种情况要求服务器和用户双方都有证书。单向认证 SSL 协议不需要客户拥有 CA 证书,具体的过程相对于上面的步骤,只需将服务器端验证客户证书的过程去掉,以及在协商对称密码方案,对称通话密钥时,服务器发送给客户的是没有加过密的 (这并不影响 SSL 过程的安全性)密码方案。 这样,双方具体的通讯内容,就是加过密的数据,如果有第三方攻击,获得的只是加密的数据,第三方要获得有用的信息,就需要对加密的数据进行解密,这时候的 安全就依赖于密码方案的安全。而幸运的是,目前所用的密码方案,只要通讯密钥长度足够的长,就足够的安全。这也是我们强调要求使用 128 位加密通讯的原因。
证书
OpenSSL建立自己的CA
(1) 环境准备
首先,需要准备一个目录放置CA文件,包括颁发的证书和CRL(Certificate Revoke List)。 这里我们选择目录 /var/MyCA。
然后我们在/var/MyCA下建立两个目录,certs用来保存我们的CA颁发的所有的证书的副本;private用来保存CA证书的私钥匙。
除了生成钥匙,在我们的CA体系中还需要创建三个文件。第一个文件用来跟踪最后一次颁发的证书的序列号,我们把它命名为serial,初始化为01。第二个文件是一个排序数据库,用来跟踪已经颁发的证书。我们把它命名为,文件内容为空。
$ mkdir /var/MyCA $ cd /var/MyCA $ mkdir certs private $ chmod g-rwx,o-rwx private $ echo "01" > serial $ touch
第三个文件是OpenSSL的配置文件,创建起来要棘手点。示例如下:
$ touch
文件内容如下:
[ ca ] default_ca = myca
[ myca ] dir = /var/MyCA certificate = $dir/ database = $dir/ new_certs_dir = $dir/certs private_key = $dir/private/ serial = $dir/serial
default_crl_days= 7 default_days = 365 default_md = md5
policy = myca_policy x509_extensions = certificate_extensions
[ myca_policy ] commonName = supplied stateOrProvinceName = supplied countryName = supplied emailAddress = supplied organizationName= supplied organizationalUnitName = optional
[ certificate_extensions ] basicConstraints= CA:false
[ req ] default_bits = 2048 default_keyfile = /var/MyCA/private/ default_md = md5 prompt = no distinguished_name = root_ca_distinguished_name x509_extensions = root_ca_extensions [ root_ca_distinguished_name ] commonName = My Test CA stateOrProvinceName = HZ countryName = CN emailAddress = test@ organizationName = Root Certification Authority [ root_ca_extensions ] basicConstraints = CA:true
(2) 生成根证书 (Root Certificate)
我们需要一个证书来为自己颁发的证书签名,这个证书可从其他CA获取,或者是自签名的根证书。这里我们生成一个自签名的根证书。
$ openssl req -x509 -newkey rsa -out -outform PEM -days 356 -config
验证一下我们生成的文件。
$ openssl x509 -in -text -noout
生成结果: private/ 是CA证书的私钥文件, 是CA证书。
制作用于CA签名的CA的私钥和公钥文件 [root@]#openssl genrsa -des3 -out ca.key 1024 //要求为key文件输入密码(,随便输入,可以和输入的PEM密码不同) [root@]#openssl req -new -x509 -days 18250-key ca.key -out ca.crt //要求输入密码以及证书信息。输入的密码要与使用的key文件的密码一致,否则会出错。
同时需要输入证书信息。以完成公钥生成。
2、制作服务器证书
a、生成服务器私钥() [root@localhost ssl.crt]#openssl genrsa -des3 -out 1024 输入加密密码(.password),用128位rsa算法密钥文件 该密码在部署客户端密钥时需要使用。 b、生成服务器证书请求() [root@localhost ssl.crt]#openssl req -new -key -out 这里要求输入的CommonName必须与通过浏览器访问您网站的 URL 完全相同,否则用户会发现您服务器证书的通用名与站点的名字不匹配,用户就会怀疑您的证书的真实性。可以使域名也可以使IP地址。 c、生成服务器公钥(证书) [root@localhost ssl.crt]#openssl ca -in -days 18250 -out server.crt -cert ca.crt -keyfile ca.key -config
d、查看和验证证书信息
[root@localhost ssl.crt]#openssl x509 -noout -text -in server.crt //查看证书信息 [root@localhost ssl.crt]#openssl verify -CAfile ca.crt server.crt //验证证书信息
一定要保证验证通过,没有报错或警告信息。否则可能会在使用时出错。
3、制作客户端证书
a、生成客户端私钥() [root@localhost ssl.crt]#openssl genrsa -des3 -out 1024 输入加密密码(.password),用128位rsa算法密钥文件 该密码在部署客户端密钥时需要使用。 b、生成客户端证书请求() [root@localhost conf]#openssl req -new -key -out Common Name 可以随便取。 c、生成客户端公钥(证书) [root@localhost ssl.crt]#openssl ca -in -days 18250 -out client.crt -cert ca.crt -keyfile ca.key -config 将证书转换成浏览器可识别的格式: [root@conf]#openssl pkcs12 -export -clcerts -in client.crt -inkey -out client.p12
需要输入Export密码,可以和Key文件密码不一样。该密码在客户端部署KEY文件时需要使用。 d、 [root@localhost ssl.crt]#openssl x509 -noout -text -in client.crt //查看证书信息 [root@localhost ssl.crt]#openssl verify -CAfile ca.crt client.crt //验证证书信息
一定要保证验证通过,没有报错或警告信息。否则可能会在使用时出错。