SSL 证书是数字证书的一种,也称为服务器 SSL 证书。它遵守 SSL 协议,由受信任的数字证书颁发机构 CA 在验证服务器身份后颁发。SSL 证书具有服务器身份验证和数据传输加密功能,可以确保在客户端和服务器之间的信息传输过程中,数据不被改变,保证数据的完整性,并防止信息泄露。 为什么需要证书 设想用户 A 要欺骗用户 B,A 可以向 B 发送一份伪造是 C 发送的报文,A 用自己的私钥进行数字签名,并附上 A 自己的公钥,谎称这公钥是 C 的。B 如何知道这个公钥不是 C 的呢? 那假如说你(客户端)拿到的公钥并不是服务端给的呢,而是黑客塞给你的呢?而你却把这个假公钥当成真的,那么当你使用这个假公钥加密一些敏感信息时,黑客就可以截取你的这段信息,由于这信息是用黑客自己的公钥加密的,这样一来,黑客拿自己的私钥就能解密得到你的敏感信息。这就是问题所在。 要解决这个问题,其实只要保证“公钥”是可信的。只有服务端发给你的公钥你才能拿,而坏人给你的公钥,你要懂得识别并丢弃它。 显然,这需要有一个值得信赖的机构来将公钥与其对应的实体(人或机器)进行绑定 (binding)。这样的机构就叫做认证中心 CA (Certification Authority)。 那么数字证书究竟是什么东西?其实它就是一个文件,包含如下信息: 公钥的提供方信息 公钥 数字证书中的公钥,能够与服务端的私钥配对使用,实现数据传输过程中的加密和解密。 CA机构的签名 证书有效时间 证书采用的加密算法 证书生成过程 在自己的服务器上生成一对公钥和私钥。然后将域名、申请者、公钥(注意不是私钥,私钥是无论如何也不能泄露的)等其他信息整合在一起,生成 .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 证书添加进信任机构,签发好的证书就不需要加...
包含 SSL 标签的文章
使用 Certbot 获取 Let’s Encrypt 证书
Let’s Encrypt https://letsencrypt.org/ Let’s Encrypt is a free, automated, and open Certificate Authority. Certbot Automatically enable HTTPS on your website with EFF's Certbot, deploying Let's Encrypt certificates. Install: On Ubuntu systems, the Certbot team maintains a PPA. Once you add it to your list of repositories all you'll need to do is apt-get the following packages. $ sudo apt-get update $ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:certbot/certbot $ sudo apt-get update $ sudo apt-get install python-certbot-nginx $ sudo certbot --nginx $ sudo certbot renew --dry-run #自动更新 执行该命令会创建系统级 cron 任务:/etc/cron.d/certbot,会每天检查两...
mkcert 本地 HTTPS 加密证书工具
mkcert 是一个使用 GO 语言编写的生成本地自签证书的小程序,具有跨平台,使用简单,支持多域名,自动信任 CA 等一系列方便的特性可供本地开发时快速创建 https 环境使用。 https://github.com/FiloSottile/mkcert Ubuntu 中安装 sudo apt install libnss3-tools wget https://github.com/FiloSottile/mkcert/releases/download/v1.3.0/mkcert-v1.3.0-linux-amd64 mv mkcert-v1.3.0-linux-amd64 mkcert chmod +x mkcert cp mkcert /usr/local/bin/ 生成并将根 CA 证书加入本地可信 CA mkcert -install Using the local CA at "/home/matt/.local/share/mkcert" ✨ The local CA is now installed in the system trust store! ⚡️ ls /home/matt/.local/share/mkcert rootCA-key.pem rootCA.pem 生成网站的证书 mkcert 192.168.1.172 将证书部署到网站后,服务器本机访问: curl -I https://192.168.1.172:8888 已经不提示证书错误了。 客户机访问仍提示证书错误(不能验证证书)。 将 rootCA.pem 副本命名为 rootCA.crt 发给客户端用户,手动导入到“受信任的根证书颁发机构”。 重启浏览器后访问网站可以看到连接变成安全的了...