标签 SSL 下的文章

Firefox 浏览器背后的 Mozilla 基金会正在考虑对沃通(WoSign)及被其秘密收购的 StartCom(著名的 StartSSL 即其旗下产品)这两个 CA 一年内新签发的所有 SSL 证书进行封杀。

Mozilla 的工程师是在对这两个 CA 签发了一系列可疑的 SSL SHA-1 证书进行调查之后,宣布了这个禁令。

这两家 CA 试图规避 SHA-1 停用政策

该问题主要是因为各大主要浏览器厂商共同决定从 2016 年 1 月 1 日开始就停止接受采用陈旧的 SHA-1 签名算法的证书。而 Mozilla 指责沃通今年还在签发 SHA-1 签名的证书,并将签发日期倒填成去年 12 月份。

虽然 Mozilla 也允许一些其它的 CA 在 2016 年 1 月 1 日之后继续签发 SHA-1 证书,比如说赛门铁克,但是他们仅允许那些通过了复杂的审批流程的 CA 这样做,而显然沃通没有得到同意。

沃通秘密收购了 StartCom

此外,沃通似乎在否认其收购了以色列 CA 公司 StartCom。Mozilla 说,沃通已经于 2015 年 11 月 1 日百分百地收购了 StartCom。而另一方面,据奇虎 360 称,它共计持有 84% 的沃通股份。但是这些信息沃通此前都予以否认或拒绝发表意见。

此外,在 Mozilla 披露的技术细节中显示,StartCom 已经开始使用沃通的基础架构来签发新的证书了。而且,StartCom 也和沃通一样在 2016 年采用了倒填日期的手段来签发 SHA-1 证书。Mozilla 的安全工程师也展示了这种违例的案例细节。

Mozilla 的调查发现,一个和 GeoTrust CA 合作了多年的付费处理机构 Tyro 突然在 6 月中旬使用 StartCom 部署了一个 SHA-1 签名的证书,而此前该机构从未和 StartCom 有过合作。该证书看起来是在 2015 年 12 月 20 日签发的,而在同一个日期 StartCom 签发大量的 SHA-1 证书。Mozlla 发现这些证书部署于 2016 年中,这很不正常,这显然是采用倒填日期来规避 SHA-1 停用的策略。

这些问题以及其它的更多问题让 Mozilla 决定在至少一年内不再信任沃通和 StartCom 的 SSL 证书。

或许会永久封杀

Mozilla 说这个临时封杀仅针对这两个公司最新签发的证书,不影响已经分发给他们的客户的证书。如果这两个公司在一年的封杀后没有通过一系列的检查,Mozilla 将准备封杀这两个公司的所有证书。

“许多人都在盯着 Web PKI 安全体系,如果发现了这样的倒填(不管是什么原因),Mozilla 会立即永久地取消对沃通和 StartCom 根证书的信任。”该报告中说。

此外,Chrome 和其它产品的对它们的封杀也在计划中。“其它的浏览器厂商和根证书存储运营者也会做出他们自己的决定,我们在这个文档中摆出了这些信息,以便他们了解我们做出这个决定的原因,并可以据此做出他们的决定。”Mozilla 说。

支持 HSTS 比你想象的更容易。

由于服务器管理员没能正确设置 HTTP Strict Transport Security (HSTS),现今大量的 HTTPS 流量都能被轻松劫持。

HSTS 是一个被当前大多数 Web 浏览器所支持的 Web 安全策略,它可以帮助 Web 管理员保护他们的服务器和用户避免遭到 HTTPS 降级、中间人攻击和 Cookie 劫持等 HTTPS 攻击的危害。

95% 的 HTTPS 连接处于风险中

据最近的 Netcraft study 报告数据显示,当前多达 95% 的服务器所运行的 HTTPS 没有正确地设置 HSTS 或其它配置,以至于将 HTTPS 连接暴露于上述攻击风险之中。

更值得注意的是,Netcraft 在三年前进行的同样扫描,不正确配置的 HSTS 比例仍同现在一样。这表明 Web 管理员们并没有学会或被告知如何正确地设置 HSTS。

针对这些不安全的站点的最容易的攻击场景是 HTTPS 降级攻击,攻击者可以选择多种方式来迫使一个看起来安全的 HTTPS 连接根本不使用数据加密或使用更弱的算法,这样攻击者就可以进行数据窃取了。

据安全研究人员称,在这 95% 的没有正确设置 HSTS 的站点中,有很多银行和金融机构的网站。

你可以通过下面一行配置激活你的 HSTS

不需要费脑筋,你只需要将下述的一行配置添加到你的 HTTPS 服务器配置中即可实现 HSTS。

Strict-Transport-Security: max-age=31536000;

这一行可以让服务器告诉浏览器仅通过 HTTPS 连接来访问其内容,其策略有效期为长达一年的最大有效时间。

当上述配置生效后,即便用户在他的浏览器中输入 URL 时写了 “http://”前缀,浏览器仍将会自动切换“https://”。

更多关于 HTTPS 及 HSTS 的技术实现细节,请参阅以下文章:

本教程描述了如何在 ISPConfig 3控制面板中更新 SSL 证书。有两个可选的方法:

  • 用 OpenSSL 创建一个新的 OpenSSL 证书和 CSR。
  • 用 ISPConfig updater 更新 SSL 证书

我将从用手工的方法更新 SSL 证书开始。

1)用 OpenSSL 创建一个新的 ISPConfig 3 SSL 证书

用 root 用户登录你的服务器。在创建一个新的 SSL 证书之前,先备份现有的。SSL 证书是安全敏感的,因此我将它存储在 /root/ 目录下。

tar pcfz /root/ispconfig_ssl_backup.tar.gz /usr/local/ispconfig/interface/ssl
chmod 600 /root/ispconfig_ssl_backup.tar.gz
现在创建一个新的 SSL 证书密钥,证书请求(CSR)和自签发证书。
cd /usr/local/ispconfig/interface/ssl
openssl genrsa -des3 -out ispserver.key 4096
openssl req -new -key ispserver.key -out ispserver.csr
openssl x509 -req -days 3650 -in ispserver.csr \
-signkey ispserver.key -out ispserver.crt
openssl rsa -in ispserver.key -out ispserver.key.insecure
mv ispserver.key ispserver.key.secure
mv ispserver.key.insecure ispserver.key

重启 apache 来加载新的 SSL 证书

service apache2 restart

2)用 ISPConfig 安装器来更新 SSL 证书

另一个获取新的 SSL 证书的替代方案是使用 ISPConfig 更新脚本。下载 ISPConfig 到 /tmp 目录下,解压包并运行脚本。

cd /tmp
wget http://www.ispconfig.org/downloads/ISPConfig-3-stable.tar.gz
tar xvfz ISPConfig-3-stable.tar.gz
cd ispconfig3_install/install
php -q update.php

更新脚本会在更新时询问下面的问题:

Create new ISPConfig SSL certificate (yes,no) [no]:

这里回答“yes”,SSL 证书创建对话框就会启动。


via: http://www.faqforge.com/linux/how-to-renew-the-ispconfig-3-ssl-certificate/

作者:Till 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

根据 Let's Encrypt 官方博客消息,Let's Encrypt 服务将在下周(11 月 16 日)正式对外开放。

Let's Encrypt 项目是由 互联网安全研究小组 ISRG,Internet Security Research Group 主导并开发的一个新型 数字证书认证机构 CA,Certificate Authority 。该项目旨在开发一个自由且开放的自动化 CA 套件,并向公众提供相关的证书免费签发服务以降低安全通讯的财务、技术和教育成本。在过去的一年中,互联网安全研究小组拟定了 ACME 协议草案,并首次实现了使用该协议的应用套件:服务端 Boulder 和客户端 letsencrypt

至于为什么 Let's Encrypt 让我们如此激动,以及 HTTPS 协议如何保护我们的通讯请参考浅谈 HTTPS 和 SSL/TLS 协议的背景与基础

Let's Encrypt

(题图来自:muylinux.com)

ACME 协议

Let's Encrypt 的诞生离不开 ACME( 自动证书管理环境 Automated Certificate Management Environment )协议的拟定。

说到 ACME 协议,我们不得不提一下传统 CA 的认证方式。Let's Encrypt 服务所签发的证书为 域名认证证书 DV,Domain-validated Certificate ,签发这类证书需要域名所有者完成以下至少一种 挑战 Challenge 以证明自己对域名的所有权:

  • 验证申请人对域名的 Whois 信息中邮箱的控制权;
  • 验证申请人对域名的常见管理员邮箱(如以 admin@postmaster@ 开头的邮箱等)的控制权;
  • 在 DNS 的 TXT 记录中发布一条 CA 提供的字符串;
  • 在包含域名的网址中特定路径发布一条 CA 提供的字符串。

不难发现,其中最容易实现自动化的一种操作必然为最后一条,ACME 协议中的 Simple HTTP 认证即是用一种类似的方法对从未签发过任何证书的域名进行认证。该协议要求在访问 http://域名/.well-known/acme-challenge/指定字符串 时返回特定的字符串。

然而实现该协议的客户端 letsencrypt 做了更多——它不仅可以通过 ACME 协议配合服务端 Boulder 的域名进行 独立 standalone 的认证工作,同时还可以自动配置常见的服务器软件(目前支持 Nginx 和 Apache)以完成认证。

Let's Encrypt 免费证书签发服务

对于大多数网站管理员来讲,想要对自己的 Web 服务器进行加密需要一笔不小的支出进行证书签发并且难以配置。根据早些年 SSL Labs 公布的 2010 年互联网 SSL 调查报告(PDF) 指出超过半数的 Web 服务器没能正确使用 Web 服务器证书,主要的问题有证书不被浏览器信任、证书和域名不匹配、证书过期、证书信任链没有正确配置、使用已知有缺陷的协议和算法等。而且证书过期后的续签和泄漏后的吊销仍需进行繁琐的人工操作。

幸运的是 Let's Encrypt 免费证书签发服务在经历了漫长的开发和测试之后终于来临,在 Let's Encrypt 官方 CA 被广泛信任之前,IdenTrust 的根证书对 Let's Encrypt 的二级 CA 进行了交叉签名使得大部分浏览器已经信任 Let's Encrypt 签发的证书。

使用 letsencrypt

由于当前 Let's Encrypt 官方的证书签发服务还未公开,你只能尝试开发版本。这个版本会签发一个 CA 标识为 happy hacker fake CA 的测试证书,注意这个证书不受信任。

要获取开发版本请直接:

$ git clone https://github.com/letsencrypt/letsencrypt

以下的使用方法摘自 Let's Encrypt 官方网站。

签发证书

letsencrypt 工具可以协助你处理证书请求和验证工作。

自动配置 Web 服务器

下面的操作将会自动帮你将新证书配置到 Nginx 和 Apache 中。

$ letsencrypt run

独立签发证书

下面的操作将会将新证书置于当前目录下。

$ letsencrypt -d example.com auth

续签证书

默认情况下 letsencrypt 工具将协助你跟踪当前证书的有效期限并在需要时自动帮你续签。如果需要手动续签,执行下面的操作。

$ letsencrypt renew --cert-path example-cert.pem

吊销证书

列出当前托管的证书菜单以吊销。

$ letsencrypt revoke

你也可以吊销某一个证书或者属于某个私钥的所有证书。

$ letsencrypt revoke --cert-path example-cert.pem
$ letsencrypt revoke --key-path example-key.pem

Docker 化 letsencrypt

如果你不想让 letsencrypt 自动配置你的 Web 服务器的话,使用 Docker 跑一份独立的版本将是一个不错的选择。你所要做的只是在装有 Docker 的系统中执行:

$ sudo docker run -it --rm -p 443:443 -p 80:80 --name letsencrypt \
            -v "/etc/letsencrypt:/etc/letsencrypt" \
            -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
            quay.io/letsencrypt/letsencrypt:latest auth

你就可以快速的为自己的 Web 服务器签发一个免费而且受信任的 DV 证书啦!

Let's Encrypt 的注意事项

  • Let's Encrypt 当前发行的 DV 证书仅能验证域名的所有权,并不能验证其所有者身份;
  • Let's Encrypt 不像其他 CA 那样对安全事故有保险赔付;
  • Let's Encrypt 目前不提供 Wildcard 证书;
  • Let's Encrypt 的有效时间仅为 90 天,逾期需要续签(可自动续签)。

对于 Let's Encrypt 的介绍就到这里,让我们一起目睹这场互联网的安全革命吧。

这是一篇快速指南,使用 OpenSSL 来生成 CA ( 证书授权中心 certificate authority )、 中级 CA intermediate CA 末端证书 end certificate 。包括 OCSP、CRL 和 CA 颁发者 Issuer 信息、具体颁发和失效日期。

我们将设置我们自己的 根 CA root CA ,然后使用根 CA 生成一个示例的中级 CA,并使用中级 CA 签发最终用户证书。

根 CA

为根 CA 创建一个目录,并进入:

mkdir -p ~/SSLCA/root/
cd ~/SSLCA/root/

生成根 CA 的 8192 位长的 RSA 密钥:

openssl genrsa -out rootca.key 8192

输出类似如下:

Generating RSA private key, 8192 bit long modulus
.........++
....................................................................................................................++
e is 65537 (0x10001)

如果你要用密码保护这个密钥,在命令行添加选项 -aes256

创建 SHA-256 自签名的根 CA 证书 ca.crt;你需要为你的根 CA 提供识别信息:

openssl req -sha256 -new -x509 -days 1826 -key rootca.key -out rootca.crt

输出类似如下:

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]:Beijing
Locality Name (eg, city) []:Chaoyang dist.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Linux.CN
Organizational Unit Name (eg, section) []:Linux.CN CA
Common Name (e.g. server FQDN or YOUR name) []:Linux.CN Root CA
Email Address []:[email protected]

创建几个文件, 用于该 CA 存储其序列号:

touch certindex
echo 1000 > certserial
echo 1000 > crlnumber

创建 CA 的配置文件,该文件包含 CRL 和 OCSP 终端的存根。

# vim ca.conf
[ ca ]
default_ca = myca

[ crl_ext ]
issuerAltName=issuer:copy 
authorityKeyIdentifier=keyid:always

[ myca ]
dir = ./
new_certs_dir = $dir
unique_subject = no
certificate = $dir/rootca.crt
database = $dir/certindex
private_key = $dir/rootca.key
serial = $dir/certserial
default_days = 730
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions
crlnumber = $dir/crlnumber
default_crl_days = 730

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = optional
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

[ myca_extensions ]
basicConstraints = critical,CA:TRUE
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
subjectAltName  = @alt_names
authorityInfoAccess = @ocsp_section

[ v3_ca ]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
subjectAltName  = @alt_names
authorityInfoAccess = @ocsp_section

[ alt_names ]
DNS.0 = Linux.CN Root CA
DNS.1 = Linux.CN CA Root
  
[crl_section]
URI.0 = http://pki.linux.cn/rootca.crl
URI.1 = http://pki2.linux.cn/rootca.crl

[ ocsp_section ]
caIssuers;URI.0 = http://pki.linux.cn/rootca.crt
caIssuers;URI.1 = http://pki2.linux.cn/rootca.crt
OCSP;URI.0 = http://pki.linux.cn/ocsp/
OCSP;URI.1 = http://pki2.linux.cn/ocsp/

如果你要设置一个特定的证书起止时间,添加下述内容到 [myca]

# format: YYYYMMDDHHMMSS
default_enddate = 20191222035911
default_startdate = 20181222035911

创建1号中级 CA

生成中级 CA 的私钥

openssl genrsa -out intermediate1.key 4096

生成其 CSR:

openssl req -new -sha256 -key intermediate1.key -out intermediate1.csr

输出类似如下:

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]:Beijing
Locality Name (eg, city) []:Chaoyang dist.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Linux.CN
Organizational Unit Name (eg, section) []:Linux.CN CA
Common Name (e.g. server FQDN or YOUR name) []:Linux.CN Intermediate CA
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

请确保中级 CA 的主题名(CN,Common Name)和根 CA 的不同。

使用根 CA 为你创建的中级 CA 的 CSR 签名:

openssl ca -batch -config ca.conf -notext -in intermediate1.csr -out intermediate1.crt

输出类似如下:

Using configuration from ca.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :ASN.1 12:'Beijing'
localityName          :ASN.1 12:'chaoyang dist.'
organizationName      :ASN.1 12:'Linux.CN'
organizationalUnitName:ASN.1 12:'Linux.CN CA'
commonName            :ASN.1 12:'Linux.CN Intermediate CA'
Certificate is to be certified until Mar 30 15:07:43 2017 GMT (730 days)

Write out database with 1 new entries
Data Base Updated

生成 CRL (包括 PEM 和 DER 两种格式):

openssl ca -config ca.conf -gencrl -keyfile rootca.key -cert rootca.crt -out rootca.crl.pem

openssl crl -inform PEM -in rootca.crl.pem -outform DER -out rootca.crl

每次使用该 CA 签名证书后都需要生成 CRL。

如果需要的话,你可以 撤销 revoke 这个中级证书:

openssl ca -config ca.conf -revoke intermediate1.crt -keyfile rootca.key -cert rootca.crt

配置1号中级 CA

给该中级 CA 创建新目录,并进入:

mkdir ~/SSLCA/intermediate1/
cd ~/SSLCA/intermediate1/

从根 CA 那边复制这个中级 CA 的证书和私钥:

cp ../root/intermediate1.key ./
cp ../root/intermediate1.crt ./

创建索引文件:

touch certindex
echo 1000 > certserial
echo 1000 > crlnumber

创建一个新的 ca.conf

# vim ca.conf

[ ca ]
default_ca = myca

[ crl_ext ]
issuerAltName=issuer:copy 
authorityKeyIdentifier=keyid:always

[ myca ]
dir = ./
new_certs_dir = $dir
unique_subject = no
certificate = $dir/intermediate1.crt
database = $dir/certindex
private_key = $dir/intermediate1.key
serial = $dir/certserial
default_days = 365
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions
crlnumber = $dir/crlnumber
default_crl_days = 365

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = optional
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

[ myca_extensions ]
basicConstraints = critical,CA:FALSE
keyUsage = critical,any
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = @crl_section
subjectAltName  = @alt_names
authorityInfoAccess = @ocsp_section

[ alt_names ]
DNS.0 = Linux.CN Intermidiate CA 1
DNS.1 = Linux.CN CA Intermidiate 1

[ crl_section ]
URI.0 = http://pki.linux.cn/intermediate1.crl
URI.1 = http://pki2.linux.cn/intermediate1.crl

[ ocsp_section ]
caIssuers;URI.0 = http://pki.linux.cn/intermediate1.crt
caIssuers;URI.1 = http://pki2.linux.cn/intermediate1.crt
OCSP;URI.0 = http://pki.linux.cn/ocsp/
OCSP;URI.1 = http://pki2.linux.cn/ocsp/

修改 [alt_names] 小节为你所需的 替代主题名 Subject Alternative names 。如果不需要就删除引入它的 subjectAltName = @alt_names 行。

如果你需要指定起止时间,添加如下行到 [myca] 中。

# format: YYYYMMDDHHMMSS
default_enddate = 20191222035911
default_startdate = 20181222035911

生成一个空的 CRL (包括 PEM 和 DER 两种格式):

openssl ca -config ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem

openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl

创建最终用户证书

我们使用新的中级 CA 来生成最终用户的证书。为每个你需要用此 CA 签名的最终用户证书重复这些步骤。

mkdir ~/enduser-certs
cd ~/enduser-certs

生成最终用户的私钥:

openssl genrsa -out enduser-example.com.key 4096

生成最终用户的 CSR:

openssl req -new -sha256 -key enduser-example.com.key -out enduser-example.com.csr

输出类似如下:

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]:Shanghai
Locality Name (eg, city) []:Xuhui dist.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Inc
Organizational Unit Name (eg, section) []:IT Dept
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

用1号中级 CA 签名最终用户的证书:

cd ~/SSLCA/intermediate1
openssl ca -batch -config ca.conf -notext -in ~/enduser-certs/enduser-example.com.csr -out ~/enduser-certs/enduser-example.com.crt

输出类似如下:

Using configuration from ca.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :ASN.1 12:'Shanghai'
localityName          :ASN.1 12:'Xuhui dist.'
organizationName      :ASN.1 12:'Example Inc'
organizationalUnitName:ASN.1 12:'IT Dept'
commonName            :ASN.1 12:'example.com'
Certificate is to be certified until Mar 30 15:18:26 2016 GMT (365 days)

Write out database with 1 new entries
Data Base Updated

生成 CRL (包括 PEM 和 DER 两种格式):

cd ~/SSLCA/intermediate1/
openssl ca -config ca.conf -gencrl -keyfile intermediate1.key -cert intermediate1.crt -out intermediate1.crl.pem

openssl crl -inform PEM -in intermediate1.crl.pem -outform DER -out intermediate1.crl

每次使用该 CA 签名证书后都需要生成 CRL。

如果需要的话,你可以撤销revoke这个最终用户证书:

cd ~/SSLCA/intermediate1/  
openssl ca -config ca.conf -revoke ~/enduser-certs/enduser-example.com.crt -keyfile intermediate1.key -cert intermediate1.crt

输出类似如下:

Using configuration from ca.conf
Revoking Certificate 1000.
Data Base Updated

将根证书和中级证书连接起来创建证书链文件:

cat ../root/rootca.crt intermediate1.crt > ~/enduser-certs/enduser-example.com.chain

将这些文件发送给最终用户:

enduser-example.com.crt
enduser-example.com.key
enduser-example.com.chain

你也可以让最终用户提供他们中级的 CSR 文件,而只发回给他们 这个 .crt 文件。不要从服务器上删除它们,否则就不能撤销了。

校验证书

你可以通过如下命令使用证书链来验证最终用户证书:

cd ~/enduser-certs
openssl verify -CAfile enduser-example.com.chain enduser-example.com.crt 
enduser-example.com.crt: OK

你也可以用 CRL 来校验它。首先将 PEM CRL 连接到证书链文件:

cd ~/SSLCA/intermediate1
cat ../root/rootca.crt intermediate1.crt intermediate1.crl.pem > ~/enduser-certs/enduser-example.com.crl.chain

校验证书:

cd ~/enduser-certs
openssl verify -crl_check -CAfile enduser-example.com.crl.chain enduser-example.com.crt

如果该证书未撤销,输出如下:

enduser-example.com.crt: OK

如果撤销了,输出如下:

enduser-example.com.crt: CN = example.com, ST = Beijing, C = CN, O = Example Inc, OU = IT Dept
error 23 at 0 depth lookup:certificate revoked

假如你已经完全配好了你的 SSL:使用了强加密算法、禁用了废弃的协议,而且你提供了 100% SHA-2 的证书链。SSL Labs 给了你一个 A+ 评分,shaaaaaaaaaaaaa.com 也没发现你使用了 SHA-1。但是,有些情况下,当你访问你的网站时,Chrome 仍旧会在 URL 栏处显示一个红叉,并且说你的网站提供了 SHA-1 证书,是“ 肯定不安全的 affirmatively insecure ” 的:

URL bar showing red cross through 'https'

这可能吗?不幸的是,有可能。你的服务器所发送的证书也许并不是你的浏览器所使用的。在迁移到 SHA-2 的过程中不应该是这样的,但是由于某些 CA 糟糕的做法和用户使用了老旧的软件,有时候会出现这样的问题。具体听我一一道来。

背景知识:证书链如何工作

一个 SSL 证书必须被 证书授权中心 certificate authority,CA 签名才是可信的。在最简单的情况下,网站的证书( 终端证书 end-entity certificate )是由浏览器所信任的 CA 的( 根证书 root certificate )直接签名的。

简单 PKI: 终端证书由根证书直接签名

浏览器校验直接由根证书签名的证书很简单:浏览器在它的根证书库里面查找终端证书的签发者,如果找到,就使用该根证书的公钥来校验终端证书的签名。

然而,终端证书很少会由根证书进行签名。相反的,终端证书是由一个“ 中间证书 intermediate certificate ”(有时候也称之为 下级 CA subordinate CA )进行签名的,而中间证书则由根证书进行签名。

典型的 PKI 是使用一个中间证书

校验一个由中间证书签名的证书是困难的。浏览器不能简单地在它的根证书库中找到签发者,因为该证书并不是由根证书签名的。相反,浏览器需要找到签名该证书的中间证书,需要的话还得迭代这个过程(中间证书也许是由其它的中间证书签名的),直到沿着这个证书链找到根证书。而事实上更复杂,因为也许从终端证书到根证书有几种可能的链路。

让浏览器找到中间证书链的最简单的办法是,让服务器告诉它。这就是为什么当你部署一个 SSL 证书时,不仅仅需要你自己的证书,还需要中间证书。不过,浏览器通常会缓存中间证书,也许会使用一个缓存的证书而不是使用由你的服务器提供的证书。这就是为什么在你全部使用了 SHA-2 之后, Chrome 也许还会显示一个红叉的原因:它并没有使用你的证书链上提供的证书,而是使用了其所缓存的 SHA-1 的证书链。

理论上,这是可以避免的,如果 CA 可以正确操作、用户也运行最新的软件的话。不幸的是,现实并不总是这样,个别情况下已知导致这个问题的原因有两个。

(注意:澄清一下,生成证书链的并不是 Chrome ,而是 Chrome 交由操作系统的加密库构建证书链。加密库在 Windows 上是 CryptoAPI,Linux 上是 NSS。)

问题一:将 SHA-1 中间证书用 SHA-2 重用

当 CA 迁移到 SHA-2 时,它可以通过对已有的公钥用 SHA-2 重新签名,从而重用已有的中间证书,或者也可以生成一个带有新的公钥和 主题名 subject name 的新中间证书。

两种新的 SHA-2 签名方式

第一种方式是错误的。虽然 CA 可以用已有的中间证书使用 SHA-2 重新签名,但是浏览器也许会缓存着带有旧的 SHA-1 签名的中间证书。如上面解释的,浏览器可以忽略由服务器提供的链证书,即便服务器发送了带有新的 SHA-2 签名的中间证书,客户端依然会使用其所缓存的 SHA-1 中间证书来构建证书链。CryptoAPI 就是这样的。

服务器发送了 SHA-2 证书,浏览器使用了缓存的 SHA-1 证书

而第二个办法就避免了缓存证书链的问题。因为 CA 生成了一个新的中间证书,有新的名字和公钥,浏览器不可能有用 SHA-1 签名的旧版本。这就是为什么 Ballot 118 在 CA/Browser Forum 这样说:

SHA-2 下级证书绝不应该链到 SHA-1 的 CA 下级证书上。

不幸的是,有些 CA 根本没在意这个忠告,比如某个 CA ,StartCom,仍然使用 SHA-1 中间证书签发 SHA-2 终端证书。虽然他们提供了一个 SHA-2 签名的中间证书,但是如果浏览器已经有一个缓存的 SHA-1 版本时就会有问题。

幸运的是,SSLMate 的两个 CA 都正确地从新的 SHA-2 中间证书签发证书,所以,SSLMate 的客户不需要担心这个。

问题二:过期的 NSS 和交叉签名的根证书

有时候根证书自身也由其它的根证书签名,通常这称之为 交叉签名 cross-signing 。这提供了一个抵达可信根证书的另外一条路径,交叉签名可以让一个不在你的浏览器的可信证书库中的新根证书也可以工作。当浏览器开始信任一个根证书时,交叉签名的证书就不再需要了。然而,和中间证书一样,交叉签名的证书也是可以缓存的,而在 NSS 中一个 bug 会导致 Linux 上的 Chrome 使用缓存的交叉签名的根证书,即使有更短和更新的证书链存在。如果这个缓存的交叉签名证书正好使用 SHA-1,Chrome 就会使用这个有问题的证书链并显示一个红叉,而不管你的服务器是否发送了全都使用 SHA-2 的证书链。

NSS 使用缓存的交叉签名证书构建证书链

这个 bug 在 NSS 3.17.4 中修复,发布于1/28。不幸的是,Debian 更新 NSS 软件包非常缓慢。这个 bug 在2014/12/30 就提交到了 Debian 的 bug tracker 上了,但是直到 5/13 都没在 Debian Unstable 中修复。同时,Debian Stable (Jessie)继续用着 NSS 3.17.2 。Debian 安全团队排除了会通过安全更新修复它,而且看起来包维护者也不像是会快速响应将这个修复加入到即将发布(本文写作时)的 Debian Stable 中。Ubuntu 则不同,将此作为安全问题,在 2/19 给其所有发行版发布了更新包。

不幸的是,CA 不能为使用过期 NSS 的用户做些什么。直到 Debian 为其稳定发行版发布更新的 NSS 包之前,Debian 上的 Chrome 用户会一直看到许多这样的红叉:

URL bar showing red cross through 'https'

或者,如果证书在 2016 年失效的话是这样:

URL bar for https://bugs.debian.org, with orange alert symbol

更新:由 SSLMate 的 Andrew Ayer 提供的 NSS 更新包,放到了 2015/9/5 发布的 Debian Jessie 8.2 中。