SSL 证书是数字证书的一种,也称为服务器 SSL 证书。它遵守 SSL 协议,由受信任的数字证书颁发机构 CA 在验证服务器身份后颁发。SSL 证书具有服务器身份验证和数据传输加密功能,可以确保在客户端和服务器之间的信息传输过程中,数据不被改变,保证数据的完整性,并防止信息泄露。
为什么需要证书
设想用户 A 要欺骗用户 B,A 可以向 B 发送一份伪造是 C 发送的报文,A 用自己的私钥进行数字签名,并附上 A 自己的公钥,谎称这公钥是 C 的。B 如何知道这个公钥不是 C 的呢?
那假如说你(客户端)拿到的公钥并不是服务端给的呢,而是黑客塞给你的呢?而你却把这个假公钥当成真的,那么当你使用这个假公钥加密一些敏感信息时,黑客就可以截取你的这段信息,由于这信息是用黑客自己的公钥加密的,这样一来,黑客拿自己的私钥就能解密得到你的敏感信息。这就是问题所在。
要解决这个问题,其实只要保证“公钥”是可信的。只有服务端发给你的公钥你才能拿,而坏人给你的公钥,你要懂得识别并丢弃它。
显然,这需要有一个值得信赖的机构来将公钥与其对应的实体(人或机器)进行绑定 (binding)。这样的机构就叫做认证中心 CA (Certification Authority)。
那么数字证书究竟是什么东西?其实它就是一个文件,包含如下信息:
证书生成过程
在自己的服务器上生成一对公钥和私钥。然后将域名、申请者、公钥(注意不是私钥,私钥是无论如何也不能泄露的)等其他信息整合在一起,生成 .csr 文件。将这个 .csr 文件发给 CA 机构,CA 机构收到申请后,会通过各种手段验证申请者的组织信息和个人信息,如无异常(组织存在,企业合法,确实是域名的拥有者),CA 就会使用散列算法对 .csr 里的明文信息先做一个 HASH,得到一个信息摘要,再用 CA 自己的私钥对这个信息摘要进行加密,生成一串密文,密文即是所说的签名。签名 + .csr 明文信息,即是证书。CA 把这个证书返回给申请人。
SSL 证书根据验证级别可以分为域名型 SSL 证书、企业型 SSL 证书、增强型 SSL 证书。按照域名数量,又可以分为单域名 SSL 证书、多域名版 SSL 证书、通配符 SSL 证书。
按照用途分为顶级证书、服务器证书和客户端证书。
顶级证书是权威证书颁发机构所持有的证书,权威机构使用顶级证书给服务器证书或客户端证书进行签名。
服务器证书是我们最常见的,访问多有 https 的网站,都会收到一个服务器证书,如果证书是有有名的权威机构颁发,则浏览器就会帮我们处理证书。如果证书是由不知名机构颁发,浏览器会跳出窗口,问我们是否信任此证书。
客户端证书常见于网银。像招商银行的客户端,可以使用电子证书。之所以存在客户端证书,原因是服务器想验证客户的合法性。这时候,信任是双向的。
一般互联网上,只需要服务器证书,信任是单向的,服务器并不对客户做验证。
自签名证书
当用于在私人网络或测试环境中时,与公共信任机构无关,我们可以自签名。OpenSSL 自签名证书是由 OpenSSL 库生成的一种数字证书,它用于加密与认证,由证书持有人本身进行签名。这样的证书一般不被第三方信任。
生成私钥
openssl genrsa -out private.pem 2048
genrsa:用于生成 RSA 密钥对的 OpenSSL 命令
-des3:使用 3-DES 对称加密算法加密密钥对,该参数需要用户在密钥生成过程中输入一个口令用于加密。今后使用该密钥时,需要输入相应的口令(服务启动时要输入)。如果不加该选项,则不对密钥进行加密。
-out:密钥保存到的文件
2048:RSA 模数位数,在一定程度上表征了密钥强度。
可以查看密钥:
openssl rsa -noout -text -in private.pem
生成公钥
在生成证书过程中其实使用不到公钥文件的。
openssl rsa -in private.pem -pubout > public.pem
数据签名认证测试
这不是证书自签名过程的环节,仅用于测试。
1、私钥签名:
echo -n A message for signing > data.txt
openssl dgst -sha1 -sign private.pem -out sha1.sign data.txt
2、公钥验签:
openssl dgst -sha1 -verify public.pem -signature sha1.sign data.txt
输出 Verified OK
说明签名验证正确。内容没有被篡改过。
自签名
虽然也可以自己扮演 CA 的角色来给证书签名,完成标准的证书申请流程。还有更简单的办法,那就是自签名。
以前生成证书的时候不需要备用名称字段(subjectAltName),现在的浏览器校验证书都需要这个字段。如果没有这个字段,即使证书的 CN(Common Name)与你的域名或 IP 是一致的,浏览器还是会提示证书无效:
NET::ERR_CERT_COMMON_NAME_INVALID
所以我们需要配置扩展信息,可以与常规信息放在一起存到一个配置文件:
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C=CN
ST=Guangdong
L=Shenzhen
O=MCULoop
OU=R&D
CN=192.168.1.100 #IP或域名
emailAddress=webmaster@localhost
[req_ext] #不一定是这个名字,但要与其他地方匹配
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names] #不一定是这个名字,但要与其他地方匹配
IP.0=192.168.1.100
IP.1=如果还有别的就这添加
DNS.0=www.mculoop.com
DNS.1=如果有别的域名也可以这样添加
保存成一个文件名(任意),比如:req.conf
如果按照标准的流程,这里应该先生成申请文件:
# openssl req -new -key private.pem -out cert.csr -config req.conf
不过我们自签名,就不用申请文件了,直接签名即可生成证书:
# openssl req -x509 -key private.pem -days 3650 -out cert.crt -config req.conf -extensions req_ext
-days 3650:从生成之时算起,证书时效为 3650 天。
-key:指定证书所使用的密钥文件
-out:生成证书文件
至此就完成自签名证书的生成了。
查看证书:
openssl x509 -noout -text -in cert.crt
自此证书就可以使用了。不过由于证书不是被浏览器信任的 CA 机构签的,所以用浏览器打开网站时仍会提示:
您的连接不是私密连接
NET::ERR_CERT_AUTHORITY_INVALID
这时把证书安装到“受信任的根证书颁发机构”存储区就可以了。
自己扮演 CA 完成签名
上面的自签名证书已经可以用了,若要体验一下完整的签名过程可以再扮演 CA 的角色来给申请文件签名。
生成 CA 根证书
其实也是 CA 自签名的过程,先按上面的过程搞出 CA 根证书。
openssl req -x509 -newkey rsa:1024 -nodes -keyout ca.key -out ca.crt -days 3650
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:SZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MCULoop
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:MCULoop CA
Email Address []:
命令已经包含了私钥文件的生成过程。
用 CA 签发证书
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in cert.csr -out cert.crt -days 3650 -extfile req.conf -extensions req_ext
如果要使用签发的证书,需要把 CA 证书添加进信任机构,签发好的证书就不需要加了。