HTTPS -ECC证书

HTTPS 通过 TLS 层和证书机制提供了内容加密、身份认证和数据完整性三大功能,可以有效防止数据被监听或篡改,还能抵御 MITM(中间人)攻击,点击了解更多Https 加密原理。TLS 在实施加密过程中,需要用到非对称密钥交换和对称内容加密两大算法。

对称内容加密强度非常高,加解密速度也很快,只是无法安全地生成和保管密钥。在 TLS 协议中,应用数据都是经过对称加密后传输的,传输中所使用的对称密钥,则是在握手阶段通过非对称密钥交换而来。常见的 AES-GCM、ChaCha20-Poly1305,都是对称加密算法。

非对称密钥交换能在不安全的数据通道中,产生只有通信双方才知道的对称加密密钥。目前最常用的密钥交换算法有 RSA 和 ECDHE:RSA 历史悠久,支持度好,但不支持 PFS(Perfect Forward Secrecy);而 ECDHE 是使用了 ECC(椭圆曲线)的 DH(Diffie-Hellman)算法,计算速度快,支持 PFS。

存在问题

并不是所有浏览器都支持 ECDHE 密钥交换,也就是说 ECC 证书的兼容性要差一些。例如在 Windows XP 中,使用 ECC 证书的网站只有 Firefox 能访问(Firefox 的 TLS 自己实现,不依赖操作系统);Android 平台中,也需要 Android 4+ 才支持 ECC 证书。

好消息是,Nginx 1.11.0 开始提供了对 RSA/ECC 双证书的支持。它的实现原理是:分析在 TLS 握手中双方协商得到的 Cipher Suite,如果支持 ECDSA 就返回 ECC 证书,否则返回 RSA 证书。

也就是说,配合最新的 Nginx,我们可以使用 ECC 证书为现代浏览器提供更好的体验,同时老旧浏览器依然会得到 RSA 证书,从而保证了兼容性。

如何申请ECC 证书

如果你的 CA 支持签发 ECC 证书,使用以下命令生成 CSR(Certificate Signing Request,证书签名请求)文件并提交给提供商,就可以获得 ECC 证书:

openssl ecparam -genkey -name secp256r1 | openssl ec -out ecc.key

openssl req -new -key ecc.key -out ecc.csr

以上命令中可供选择的算法有 secp256r1 和 secp384r1,secp521r1 已被 Chrome 和 Firefox 废弃。

我目前在用的 Let’s Encrypt,也支持签发 ECC 证书。我使用了 acme.sh 这个小巧的工具来签发证书,指定 -k ec-256 就可以将证书类型改为 ECC:

“/root/.acme.sh”/acme.sh –issue –dns dns_cx -d imququ.com -d www.imququ.com -k ec-256

目前 Let’s Encrypt 只提供 RSA 中间证书,官方预计会在 2017 年 3 月底提供 ECC 中间证书(via)。

如何使用

有了 RSA/ECC 双证书之后,还需要安装 Nginx 1.11.x。

一切准备妥当后,将证书配置改为双份即可:

ssl_certificate     example.com.rsa.crt;

ssl_certificate_key example.com.rsa.key;

ssl_certificate     example.com.ecdsa.crt;

ssl_certificate_key example.com.ecdsa.key;

测试环境使用 Cloudflare 提供的 Cipher Suites 配置,在 Nginx 中配置了双证书并重启,用 Chrome 测试发现仍然没有采用 ECC 证书。这是为什么呢?

# https://www.evtrust.com/cloudflare/sslconfig/blob/master/conf

ssl_ciphers                 EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

ssl_prefer_server_ciphers   on;

研究发现,Chrome 与服务端协商到的 Cipher Suites 是 ECDHE-RSA-AES128-GCM-SHA256,来自于 ssl_ciphers 配置中的 EECDH+AES128 这部分。我们通过 openssl 工具看一下 EECDH+AES128 具体包含哪些 Cipher Suites:

openssl ciphers -V ‘EECDH+AES128’ | column -t

0xC0,0x2F  –  ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD

0xC0,0x2B  –  ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD

0xC0,0x27  –  ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256

0xC0,0x23  –  ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256

0xC0,0x13  –  ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1

0xC0,0x09  –  ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1

可以看到,使用 RSA 做为签名认证算法(Au=RSA)的加密套件排到了前面,导致 Nginx 作出了错误判断。

知道原因就好办了,将这段配置改为 EECDH+ECDSA+AES128:EECDH+aRSA+AES128,再看一下:

openssl ciphers -V ‘EECDH+ECDSA+AES128:EECDH+aRSA+AES128’ | column -t

 

0xC0,0x2B  –  ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD

0xC0,0x23  –  ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256

0xC0,0x09  –  ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1

0xC0,0x2F  –  ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD

0xC0,0x27  –  ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256

0xC0,0x13  –  ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1

这下就没问题了。

并不是所有加密套件都需要把 ECDSA 和 aRSA 分开写,例如 EECDH+CHACHA20 就不需要,ECDSA 默认就在前面:

openssl ciphers -V ‘EECDH+CHACHA20’ | column -t

0xCC,0xA9  –  ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=ChaCha20-Poly1305  Mac=AEAD

0xCC,0xA8  –  ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2  Kx=ECDH  Au=RSA    Enc=ChaCha20-Poly1305  Mac=AEAD

最终,我的 Cipher Suites 配置如下,供参考:

ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

Symantec EV 代码签名证书

Symantec(VeriSign) Extended Validation(EV) Code Signing Certificates
Symantec EV 代码签名证书具有标准代码签名证书的所有功能,能签名内核代码,不同的是采用更加严格国际标准扩展验证(Extended Validation:EV验证),并且有严格的证书私钥保护机制–必须采用 USB Key来保护签名证书的私钥,以防止证书被非法盗用,确保代码签名证书安全。

代码签名证书能验证软件的来源和代码的完整性,使用者也会知道该代码程序自发布后未遭到非法窜改,从而对软件开发商产生高度信赖感,保护了软件开发商的利益,使得软件开发商能安全地快速地通过互联网发布软件。

在Windows 10中标准代码签名证书无法用于内核模式驱动签名,必须用EV 代码签名证书签名。Symantec EV代码签名证书在标准代码签名证书已有的优点和基础上,增加了更加严格的开发商的身份审核,并将证书存储在USB key中,杜绝了证书被盗用的风险;能帮助已经签名的代码在Windows SmartScreen®中快速建立自己的声誉,并减少系统的用户信任警告信息。

Symantec(VeriSign) EV代码签名证书特点
● 最严格的企业身份信息扩展验证(EV),材料齐全,3~5个工作日审核验证颁发证书;

● 支持 Windows 32位和64位用户模式下 .exe, .dll, .cab, .ocx( ActiveX )等应用程序文件数字签名 ;

● 支持 Windows (包括Windows 10)32位和64位内核模式下 .sys, .cat,等驱动程序文件数字签名 ;

● 提供最为严格的证书私钥保护机制,比如通过USB Key保护证书私钥;

● 支持 Windows 硬件认证,可以用它建立Windows开发人员中心硬件仪表板账号;

● 可消除 Internet Explorer 以及 Windows 操作系统中弹出的「不明发行商」;支持Silverlight 4应用程序;

● 保护您的代码的完整性 (未被篡改或破坏 );

● 免费提供时间戳服务,确保已经签名的代码长期有效 ;

● 代码签名证书在有效期内可以不限次数对软件进行签名;

● 支持SHA)1 和 SHA 2 签名算法;

● 相对其他代码签名供应商,支持更多的平台,比如:基于云和移动应用平台;

● 严格地实行每年一次的KPMG(毕马威)审计;

Symantec(VeriSign) EV 代码签名证书和标准代码签名证书对比如下:

Symantec(VeriSign) 代码签名证书 5大理由

1、可支持更多平台,让您最大限度地提高软件分发量,从而提供您的收入
2、依靠全球最权威、最受信任的证书颁发机构(CA)减少安全警告
3、保护您的代码完整性和您的信誉
4、通过简化安全保障,加快产品上市速度
5、确保让客户获得安全可靠的体验

友情提醒
Symantec EV 代码签名证书仅限于单位用户申请,个人不能申请EV 代码签名证书 ,Symantec EV 代码签名证书需要邮寄,申请周期比较长。任何用户都不得使用Symantec EV 代码签名证书为间谍软件(Spyware)、流氓软件和黑客软件等进行数字签名,否则,一经举报和查实,我们有权立刻吊销此证书,不退款,而且还会配合公安部门和其他机构追究可能由此带来的一切法律责任。

文章来源易维信官网: http://www.evtrust.com/symantec/ev-code-signing.html

微软WHQL提交需要使用EV代码签名证书

微软曾经宣布每个WHQL提交的测试包都必须使用EV代码签名证书进行签名,没有EV代码签名的提交包将会被微软拒绝。微软最初提出这样的要求主要是出于账户安全的考虑,防止账号被滥用发布恶意驱动。

但是,目前微软收到许多WHQL合作伙伴反馈,这一要求带来了非常多的不方便。每个提交都使用EV代码签名证书使得很多大公司无法适应。一般来说,CA只会给一个公司颁发一个EV代码签名证书Ukey, 而在大的PC 硬件公司每个部分可能都需要提交WHQL。 在一些超大型公司里往往无法确认这个UKey到底在哪个部门;大公司各部门的资源调动需要走一定的流程。也建议这些公司联系易维信(http://www.evtrust.com)同时申请不同CA的EV代码签名证书,例如DigiCert EV 代码签名证书,GlobalSign EV 代码签名证书或者 Symantec 赛门铁克 EV 代码签名证书。

为了解决合作伙伴的这些烦恼,微软不再要求每个提交都使用EV代码签名证书。但在每个sysdev账户还是必须要有至少有一个EV代码签名证书,主要是做建账户的身份验证。当然,出于安全考虑微软还是鼓励伙伴们使用EV代码签名证书来做WHQL提交。