自从明月开始使用 acme.sh 来申请和管理 Let's Encrypt 证书以来(参考【Linux 下使用 acme.sh 申请和管理 Let’s Encrypt 证书】一文)一直都很叹服 acme.sh 的强大和贴心。随着年末的两个独立域名备案通过并启用,越来越感觉自己当前使用 Let's Encrypt 证书的方式太混乱了,特别是在使用 CDN 的情况下,每三个月一次的新旧证书替换效率太低了,于是就在年假期间着手对当前使用的 Let's Encrypt 证书进行了一次整理优化。
因为早期在启用站点 SSL 证书的时候是分批次进行的,加上使用了不少的二级域名,所以就造成这些域名的证书都是是单个域名为主在不同时间段申请的证书,一个两个的时候管理起来是没有问题的,现在加上年前两个新独立域名后,大大小小的算下来需要申请 10 多个 SSL 证书。这也太恐怖了,也很不科学呀!经过分析后发现其实完全可以把二级域名证书都集成在主域名证书里的,这样一来无论要使用哪个二级域名都只需要使用主域名的证书即可,一个证书对应多个二级域名情况下,在使用和部署 CDN 的时候就方便了很多,导入一个证书文件就可以将所有二级域名都包括了,很科学,有没有?
在整理证书的时候又发现既然证书数量精简了,为啥不对证书做一次“优化”呢?其实对于所谓证书的“优化”无非就是提升一下安全性和加密解密速度而已。Nginx 自 1.12 版本开始已经支持双证书的智能自动适配切换了,所以申请和使用双证书也就自然不可少了。
所谓“双证书”其实就是 SSL 证书加密算法不同的两个证书而已,Let's Encrypt 就支持同时申请同域名不同加密算法的证书,也就是RSA 加密算法和ECC 加密算法(椭圆加密算法),俗称 ECC+RSA 双证书。双证书支持可以在 TLS 握手的时候根据客户端支持的加密方法选择对应的证书,以向下兼容古代客户端(比如 Windows XP 或者 Android 2.3、Android 4.0 以下等等)。借助 Let's Encrypt 的 ACME 协议,acme.sh 脚本就可以直接申请获取不同加密算法的 SSL 证书,具体的命令行如下所示:
acme.sh --issue --dns dns_cx -d www.ymanz.com -d ymanz.com -d avatar.ymanz.com -d blog.ymanz.com -d lnmp.ymanz.com -d lnmppic.ymanz.com -d eat.ymanz.com -d eatimg.ymanz.com
acme.sh --issue --dns dns_cx -d www.ymanz.com -d ymanz.com -d avatar.ymanz.com -d blog.ymanz.com -d lnmp.ymanz.com -d lnmppic.ymanz.com -d eat.ymanz.com -d eatimg.ymanz.com -k ec-256
上述命令行都是采用的 DNS API 的方式来验证域名所有权的,所以大家要事先导入自己 DNS 解析服务的 API 到 acme.sh 里才可以的,具体大家可以参考【Linux 下使用 acme.sh 申请和管理 Let’s Encrypt 证书】一文即可。
获取了 ECC、RSA 证书后只需要在 Nginx 里同时引用这两个证书即可,Nginx 就会在 TLS 握手的时候根据客户端支持的加密方法选择对应的证书,这些其实百度一下可以找到不少的参考资料的,明月就不再多赘述了,如果大家有啥不明白的可以在本文评论里提问,明月会一一作答的!
ECC 加密算法(椭圆加密算法)小知识
椭圆加密算法(ECC)是一种公钥加密体制,最初由 Koblitz 和 Miller 两人于 1985 年提出,其数学基础是利用椭圆曲线上的有理点构成 Abel 加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类:大整数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。
优点
与经典的 RSA,DSA 等公钥密码体制相比,椭圆密码体制有以下优点:
安全性高
处理速度快
公钥密码系统的加密算法 ECC 与 RSA 的对比
第六届国际密码学会议对应用于公钥密码系统的加密算法推荐了两种:基于大整数因子分解问题(IFP)的 RSA 算法和基于椭圆曲线上离散对数计算问题(ECDLP)的 ECC 算法。RSA 算法的特点之一是数学原理简单、在工程应用中比较易于实现,但它的单位安全强度相对较低。目前用国际上公认的对于 RSA 算法最有效的攻击方法--一般数域筛(NFS)方法去破译和攻击 RSA 算法,它的破译或求解难度是亚指数级的。ECC 算法的数学理论非常深奥和复杂,在工程应用中比较难于实现,但它的单位安全强度相对较高。用国际上公认的对于 ECC 算法最有效的攻击方法--Pollard rho 方法去破译和攻击 ECC 算法,它的破译或求解难度基本上是指数级的。正是由于 RSA 算法和 ECC 算法这一明显不同,使得 ECC 算法的单位安全强度高于 RSA 算法,也就是说,要达到同样的安全强度,ECC 算法所需的密钥长度远比 RSA 算法低(见表 1 和图 1)。这就有效地解决了为了提高安全强度必须增加密钥长度所带来的工程实现难度的问题.
证书整理、优化完成了,目前也基本可以肯定明月所有的博客站点都会使用 HTTPS 下去的,所以把自己的站点域名都加入 HSTS Prelod List(预加载表)以求让各个主流浏览器都默认以 HTTPS 方式访问,省却 HTTP 请求这一步骤来提高 HTTPS 访问效率也就不可避免了。为了提高申请效率就先以 imydl.tech 为“小白鼠”来试验性提交申请,折腾了近两天终于算是成功了(可参考【本博客已启用 ECC+RSA 双证书和加入 HSTS Prelod List 预加载列表】一文),这样下来积累了经验心得后终于让 imydl.com 也顺利的加入到了(这个折腾 10 分钟就搞定了),上说其实都是申请加入的过程,确认被加入一般需要 1-2 周后才可以查询到的,据说是因为所有申请都会被“人工审核”才会这么慢的。
至于说加入 HSTS Prelod List(预加载表)的好处,明月个人认为最大的好处就是让各个主流浏览器/内核(谷歌 Chrome、Firefox、IE 11 or EDGE、Opera、Safari 等等)放弃 HTTP 请求只使用 HTTPS 请求来访问自己的站点加快启用 HTTPS 后载入时间。当然还有就是可以没事儿“装个逼”啥的,至少“逼格”还是可以提升不少的!目前就明月所知,【张戈博客】是加入了 HSTS Prelod List(预加载表)的,两周后明月的【明月登楼的博客】和【明月登楼学习笔记 Blog】也算是加入了 HSTS Prelod List(预加载表),其实我还是喜欢“让你的域名「嵌入」主流浏览器,一同发行!”这个说法,听起来“逼格”高出了不少。
对了,申请加入 HSTS Prelod List(预加载表)的网址是:https://hstspreload.org/,国内有些省份宽带访问可能需要“访问外国网站”才可以的,至少明月在我们这里的电信宽带下是无法正常访问的,联通宽带确可以,又是个天朝无法解释的问题,唉!
最后明月建议还在持续观望 HTTPS 的站长们尽早启用 SSL 部署吧,当前国内的互联网安全趋势强迫我们必须要在安全上重视起来,HTTPS 是安全的第一步也是最基础的。这个“安全”绝不仅仅是针对网站浏览用户的对于我们站长来说就是保护我们自身利益,对那些流量劫持、域名劫持、DNS 污染、iFrame 引用等等让站长们深恶痛疾的流氓行为 HTTPS 都都可以有效抵御遏制,越早部署 SSL 实现 HTTPS 化未来遭受损失和伤害的可能性就越小,毕竟网站都是每个站长的“心血”呀!最终“为他人做了嫁衣裳”那就真的是“得不偿失”了!
其实今天讲的这些“百度一下”或者“谷歌一下”都可以找到大把的相关资料,专门的撰文记录下来主要是明月自己动手实操了,网上很多的资料都是没有“实操”的时候看着都差不多,一旦实际操作起来差距就体现出来了,甚至很多时候实操可以积累很多宝贵的经验,明月对此绝对是受益良多。
这次对 Let's Encrypt 证书申请方式、方法又有了一个全新的认识,使用 acme.sh 管理证书也是越来越顺手了!原来主域名、二级域名证书一起整合起来申请和管理这么“爽”!ECC+RSA 双证书其实没有那么“高大上”,也就是多申请一次 SSL 证书(加个参数而已),在 Nginx 里多引用一个 SSL 证书即可。其实很多东西只要是原理明白了也就“一通百通”了,要想理解原理不外乎就是“实操”了!玩这些东西其实就是要求大家“动手能力”强而已。
注意事项
ECC+RSA 双证书模式虽然 Nginx 完美的支持了,但是如果你有使用 CDN 的话,这个双证书就会失效,因为用户访问到的都是 CDN 节点而已,证书自然也是 CDN 上你导入的证书,如果单给 CDN 导入 ECC 证书的话,有不少 CDN 是不支持 ECC 证书的(比如 360 网站卫士),同时让 CDN 只使用 ECC 证书会有客户端兼容性的问题。目前来看比较适合双证书玩法的 CDN 首选还是又拍云 CDN ,兼容性上真心还是很不错的。
在申请加入 HSTS Prelod List(预加载表)时,一般首选验证的域名方式是不带 WWW 的主域名,所以请务必保证在申请时你的 DNS 解析里不带 WWW 的主域名有对应的解析并可以正常的 HTTPS 访问(Let's Encrypt 证书务必是主域名(不带 WWW)+子域名(带 WWW)集合在一起的),这点儿尤为重要,为此明月折腾了很久才算是明白,仅仅 Nginx 里的 301 跳转是不行的,必须有对应的 DNS 解析才可以的。