(2018.6.1 Update)注:此文章所用方法已过时,仅适用于OpenSSL 1.1.1-dev,不适用于其后发布的任何Alpha与Beta版本。
OpenSSL 1.1.1的Alpha与Beta版本可通过配置文件命令PrioritizeChaCha
来实现同样功能。
修改过的s3_lib.c
和生成的.patch
文件皆已发表至Github(https://github.com/Hardrain980/sslconfig_openssl_1.1.1)
CloudFlare提供了用于OpenSSL 1.0.2和1.1.0的CHACHA20 Patch。
- 对于原生不支持CHACHA20的OpenSSL 1.0.2,打Patch可令其支持CHACHA20并在不支持AES指令集的设备上优先使用CHACHA20加密套件
- 对于原生支持CHACHA20的OpenSSL 1.1.0,打Patch可令其在不支持AES指令集的设备上优先使用CHACHA20加密套件
CloudFlare提供的Patch的OpenSSL 1.1.0版本经测试,在1.1.0e,1.1.0f和最新的1.1.0g上皆可正常使用;然而将其用于OpenSSL 1.1.1-dev,却报错了……
根据OpenSSL的说法,OpenSSL 1.1.1-dev与1.1.0是Binary Compatible(二进制兼容?)的。我推测是由于前者添加了对TLS 1.3的支持,导致部分代码的行号发生改变,而打Patch是基于行号进行修改,故导致不能Patch。
经分析,该Patch仅对{OPENSSL_SOURCE_PATH}/ssl/s3_lib.c
进行了修改,修改了4处。
.patch
文件用diff
生成,其中以+
开头代表添加的行;以-
开头代表删去的行;而无+
/-
的则是修改处的上下文。
基于此,我在OpenSSL 1.1.1-dev的s3_lib.c
中查找.patch
文件中的"上下文",并"手动patch"——尽管我完全不懂C语言,但只要照葫芦画瓢,将这些新加的代码根据上下文插入即可。编辑完后替换s3_lib.c
,重新编译后,无论TLS 1.2抑或TLS 1.3,都能正确选择加密套件(AES-GCM/CHACHA20)。
注1:CHACHA20加密套件应排在最前,无论是否启用TLS 1.3。应按照如下顺序设置SSL加密套件
- 不使用TLS 1.3,
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:*
- 使用TLS 1.3,
TLS13-CHACHA20-POLY1305:TLS13-*:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:*
注2:目前仅已知nginx的较新版本能使用TLS 1.3;最新版本的Apache尽管与OpenSSL 1.1.1-dev可成功编译,但不能使用TLS 1.3。
确认"手动patch"成功后,使用diff -Naru {$ORIGINAL_FILE} {$PATCHED_FILE} > filename.patch
生成.patch
文件。
Demo:https://0o1o0.tk
使用SSL Labs检测:
实测:
- 左为Nexus 6,采用不支持AES指令集的Snapdragon 805
- 右为OnePlus 5,采用支持AES指令集的Snapdragon 835
TLS 1.2:
![]() |
![]() |
TLS 1.3:
![]() |
![]() |