关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » HTML5 »使用 BoringSSL 优化 HTTPS 加密算法选择

    使用 BoringSSL 优化 HTTPS 加密算法选择

    2015-10-20 00:00:00 出处:左小田
    分享

    前不久,一位朋友在我博客评论中,问到:类似于 Google 那样电脑访问使用 AES,手机访问使用 CHACHA20 的算法是怎么实现的。最近我研究了一下这个问题,现在我的博客也支持这个特性了。今天抽空介绍一下我的实现步骤,供喜欢折腾的朋友们参考。

    使用 BoringSSL 优化 HTTPS 加密算法选择

    对称内容加密

    我们知道,每个 TLS 会话都是在握手阶段通过非对称加密得出对称加密密钥,而本次会话双方一直会用这个密钥进行流量的对称加密。这样做是出于性能考虑,毕竟对称加密速度要快得多,更适合全流量使用。

    对称加密算法有流式、分组两种。RC4 就是一个常见的流式加密算法,不过已被证实不再安全,应该停止使用。Google 推出了一种名为 ChaCha20-Poly1305 的流式加密新算法,已经内置于各大平台的 Chrome 之中。ChaCha20 除了更安全,还针对 ARM 做了优化,在移动设备上使用速度更快、更省电。以下是它与 AES-GCM 在加密速度上的对比:

    AES-GCM 是目前推荐使用的分组加密模式,它的缺点是计算量大,导致性能和电量开销比较大。为此,Intel 推出了一个名为 AES NI(Advanced Encryption Standard new instructions)的 x86 指令集扩展,从硬件上提供对 AES 的支持。Intel 自家 CPU 从 Westmere 平台开始支持 AES-NI,目前在 PC 端 AES-NI 的普及率显然很高。对于支持 AES-NI 的设备来说,使用 AES-GCM 加密算法无疑是最优选择,以下是一份对比(测试使用支持 AES-NI 的 Intel Xeon E3-1220 V2 @ 3.10GHz):

    Did 20341000 AES-128-GCM (16 bytes) seal operations in 3000099us (6780109.6 ops/sec): 108.5 MB/s
    Did 2356000 AES-128-GCM (1350 bytes) seal operations in 3000761us (785134.2 ops/sec): 1059.9 MB/s
    Did 438000 AES-128-GCM (8192 bytes) seal operations in 3002910us (145858.5 ops/sec): 1194.9 MB/s
    Did 17839000 AES-256-GCM (16 bytes) seal operations in 3000160us (5946016.2 ops/sec): 95.1 MB/s
    Did 2092000 AES-256-GCM (1350 bytes) seal operations in 3000884us (697127.9 ops/sec): 941.1 MB/s
    Did 388000 AES-256-GCM (8192 bytes) seal operations in 3004207us (129152.2 ops/sec): 1058.0 MB/s
    Did 7779000 ChaCha20-Poly1305 (16 bytes) seal operations in 3000332us (2592713.1 ops/sec): 41.5 MB/s
    Did 1139000 ChaCha20-Poly1305 (1350 bytes) seal operations in 3001412us (379488.1 ops/sec): 512.3 MB/s
    Did 220000 ChaCha20-Poly1305 (8192 bytes) seal operations in 3006395us (73177.3 ops/sec): 599.5 MB/s

    可以看到,尽管纯软件实现的 ChaCha20 算法已经十分优秀,但跟有 AES-NI 加持的 AES-GCM 比起来还是差距明显。

    综上,我们很容易想到「仅针对支持 AES-NI 的终端使用 AES-GCM 算法,否则使用 ChaCha20」无疑是一个非常完美的方案。

    BoringSSL

    之前文章介绍过,基于 LibreSSL 编译 Nginx,可以轻松地使用 ChaCha20。但问题是一旦配置了 ChaCha20,只要终端支持,无论桌面设备还是移动设备都会使用它。

    BoringSSL 是 Google 从 OpenSSL 拉出来的一个独立发展的分支,目前跟 OpenSSL 相比已经有很多不同之处了。BoringSSL 支持了一种名为「等价加密算法组(Equal preference cipher groups)」的配置,正好可以满足我们这个需求。

    基于 BoringSSL 编译 Nginx 之后,可以像下面这样配置 ssl_ciphers:

    ssl_ciphers [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:DES-CBC3-SHA;

    方括号之中的配置就是「等价加密算法组」,用竖线隔开的两种算法,会被自动应用于最合适的场景(支持 AES-NI 优先使用 AES-GCM,否则优先使用 ChaCha20)。最后的 DES-CBC3-SHA 是为了支持 Windows XP 上的 IE8 而加上去的。

    下图中,同样是访问本博客,左侧是 Mac Chrome 的截图,右侧是 iPhone Chrome 的截图:

    可以看到,只有移动端才使用了 ChaCha20。

    这里简单介绍一下「等价加密算法组」的原理:我们知道客户端建立 TLS 连接时,在发送的 Client Hello 中会带上自己支持的加密算法,供服务端从中挑选。由于老旧客户端会支持一些不安全的加密算法,为了提高传输安全,通常会在服务端指定一个可用算法列表,最终使用的加密类型取决于二者的交集,并按服务端优先级取第一个;假如没有交集,直接终止会话。在 Nginx 中这个功能通过将 ssl_prefer_server_ciphers 设置为 on 开启。

    那么问题来了,对于同时支持 AES-GCM 和 ChaCha20 的 Chrome 来说,服务端列表无论把哪个放前面都会导致另外一个完全没机会被选中。而「等价加密算法组」的意义在于,等价组内的算法具有相同优先级。这样,客户端可以把想要优先使用的加密算法放在前面。举例说明二者的区别(开启ssl_prefer_server_ciphers 条件下):

    不支持等价组时,假如服务端列表是:A、B、C,浏览器 1 支持:A、B,最终使用 A;浏览器 2 支持 B、A,最终使用 A,浏览器 3 支持 C、A,最终使用 A; 支持等价组时,假如服务端列表是:[A|B]、C,浏览器 1 支持:A、B,最终使用 A;浏览器 2 支持 B、A,最终使用 B,浏览器 3 支持 C、A,最终使用 A;

    可以看到,开启 ssl_prefer_server_ciphers 可以让会话使用最安全的加密算法(前提是服务端配置正确),而「等价加密算法组」还可以让浏览器有局部调整的权限。

    补充一下通过 Mac Chrome 和 iPhone Chrome 分别访问我的博客发送的加密算法列表(使用 wireshark 抓包,在 Client Hello 握手中可获得):

    Mac Chrome:

    Cipher Suites (17 suites)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc14)
    Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc13)
    Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc15)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0×0039)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0×0033)
    Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
    Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0×0035)
    Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
    Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
    Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

    iPhone Chrome:

    Cipher Suites (15 suites)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc14)
    Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc13)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0×0033)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0×0039)
    Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
    Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
    Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0×0035)
    Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

    可以看到,Chrome 浏览器确实是会在不同平台上发送不同顺序的算法列表,只要服务端配置了「等价加密算法组」就可以实现本文所描述的功能。

    最后提醒大家:现阶段 BoringSSL 不支持 OCSP Stapling。改用 BoringSSL 后,假如在 ssllabs 测试中发现这一项变成 off 不要吃惊。

    详细配置步骤

    之所以把这部分内容放在最后,是因为折腾起来有点费劲,嫌麻烦的同学可以直接忽略之后所有内容。

    以下步骤在我两台系统为 Ubuntu 14.04.3 的 VPS 上都能正常执行。假如你遇到了问题,请留言指出。

    首先,获取编译所需的 Nginx 和 BoringSSL 源码,Nginx 从 1.7.4 开始支持 BoringSSL,这里我直接使用最新版:

    SHELLwget http://nginx.org/download/nginx-1.9.5.tar.gz
    tar xzf nginx-1.9.5.tar.gz
    
    git clone https://boringssl.googlesource.com/boringssl

    现在,当前目录下应该有这两个子目录:

    boringssl/
    nginx-1.9.5/

    确认无误后,还要做一些准备工作:

    SHELL# 安装编译 BoringSSL 所需的 Golang
    sudo apt-get install golang
    
    # 忽略编译过程中的 Warning(不加这个,编到一半会因为 Warning 太多无法继续)
    export CFLAGS="-Wno-error"

    编译 BoringSSL:

    SHELL# 进入 BoringSSL 源码根目录
    cd boringssl
    
    # 创建 build 目录并编译,完成后回到 BoringSSL 源码根目录
    mkdir build && cd build && cmake ../ && make && cd ../
    
    # 创建 .openssl 目录,并将库文件和编译后的文件放进去
    mkdir -p .openssl/lib && cd .openssl && ln -s ../include . && cd ../
    cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib

    现在可以编译 Nginx 了:

    SHELL# 进入 Nginx 源码根目录
    cd nginx-1.9.5
    
    # 修改时间,避免 Nginx 再次编译 BoringSSL
    touch ../boringssl/.openssl/include/openssl/ssl.h
    
    # 指定使用 BoringSSL 作为 SSL 库
    ./configure --with-openssl=../boringssl --with-http_v2_module --with-http_ssl_module

    一切无误后可以开始 make 和 make install 了。这期间可能还会遇到这样一个报错:

    ‘SSL_R_BLOCK_CIPHER_PAD_IS_WRONG’ undeclared

    这是因为 BoringSSL 删掉了这个变量。找到报错文件中对应的位置,例如:

        || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */

    删掉这一行,或者加个判断都可以解决问题:

    SHELL#ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG
        || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */
    #endif

    其他应该没什么问题了。make install 之前记得先停掉 nginx 服务,不然很可能需要手动杀死之前的 nginx 进程。一切妥当后,参考前文修改ssl_ciphers 并启动服务,搞定收工!

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。