我应该如何继续升级到 TLS 1.2?
为了满足技术要求,使用 OpenSSL 1.0.1 或 1.0.2 就足够了。两者都提供 TLS 1.2,并且都提供 SHA-256。(还有其他隐藏的实现,例如 OpenSSL 1.0.0 不提供 EC 设备的完整补充和 TLS 1.2 密码套件的完整补充,但 1.0.1 和 1.0.2 提供)。
在使用 OpenSSL 的 C 代码中,您需要为 SSL 上下文或会话做的所有事情:
/* Useless return value ??? */
SSL_library_init();
const SSL_METHOD* method = SSLv23_method();
if(NULL == method) handleFailure();
SSL_CTX* ctx = SSL_CTX_new(method);
if(ctx == NULL) handleFailure();
/* Cannot fail ??? */
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | \
SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION;
SSL_CTX_set_options(ctx, flags);
对于类似 Apache 的服务器配置,请使用以下内容(我的包括+TLSv1 +TLSv1.1
):
# From my CentOS production server
SSLProtocol -all +TLSv1.2
您可能也应该倾向于加密套件。为此,在 C 代码中:
const char CIHPHER_LIST[] = "HIGH:!aNULL:!RC4:!MD5"
/* Ensure at least one cipher suite is added, which indicates non-failure */
int rc = SSL_CTX_set_cipher_list(ctx, CIHPHER_LIST);
if(!(rc >= 1)) handleFailure();
在类似 Apache 的配置文件中:
# From my CentOS production server
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
如果您想避免 RSA 密钥传输(TLS 1.3 正在删除它),那么:
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4:!kRSA
当您删除 RSA 密钥传输时,您几乎只剩下临时密钥交换协议(PSK 和 SRP 等模密码套件)。
如果您想显式使用临时密钥交换,那么您将需要类似kEECDH:kECDHE:kDHE:kEDH:!aNULL
. 有关更多详细信息,请参见openssl ciphers(1)
手册页。
我在字里行间阅读,但 TLS 1.2 要求可能与经过身份验证的加密以及 GCM 等操作模式有关。为此,openssl ciphers(1)
再次使用:
$ openssl ciphers -v 'HIGH:!aNULL' | grep GCM
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD
AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD
AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD
或者:
$ openssl ciphers -v 'HIGH:!aNULL' | grep GCM | grep -v "Kx=RSA" | cut -d " " -f 1
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
DHE-DSS-AES256-GCM-SHA384
DHE-RSA-AES256-GCM-SHA384
ECDH-RSA-AES256-GCM-SHA384
ECDH-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-GCM-SHA256
DHE-DSS-AES128-GCM-SHA256
DHE-RSA-AES128-GCM-SHA256
ECDH-RSA-AES128-GCM-SHA256
ECDH-ECDSA-AES128-GCM-SHA256
您可以执行以下操作,而不是指定HIGH:!aNULL:!MD5:!RC4:!kRSA
:
const char CIPHER_LIST[] =
"ECDHE-RSA-AES256-GCM-SHA384:"
"ECDHE-ECDSA-AES256-GCM-SHA384:"
"DHE-DSS-AES256-GCM-SHA384:"
"DHE-RSA-AES256-GCM-SHA384:"
"ECDH-RSA-AES256-GCM-SHA384:"
"ECDH-ECDSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES128-GCM-SHA256:"
"ECDHE-ECDSA-AES128-GCM-SHA256:"
"DHE-DSS-AES128-GCM-SHA256:"
"DHE-RSA-AES128-GCM-SHA256:"
"ECDH-RSA-AES128-GCM-SHA256:"
"ECDH-ECDSA-AES128-GCM-SHA256:"
/* Ensure at least one cipher suite is added, which indicates non-failure */
int rc = SSL_CTX_set_cipher_list(ctx, CIPHER_LIST);
if(!(rc >= 1)) handleFailure();
如果您查看AES256-GCM-SHA384
密码套件,您会看到使用密钥传输 ( Kx=RSA
),因此您可能希望避免使用它,即使它是 TLS 1.2。Hece 的原因grep -v
就可以了。
为了完整性,Au=RSA
很好。这只是意味着服务器仅使用其 RSA 密钥进行签名。实际上,Au=DSS
很少使用,因此如果没有 DSS 密钥,OpenSSL 将删除密码套件。
现在,困难可能在于获得一个提供最新 OpenSSL 1.0.2并提供长期支持的发行版。我的 CentOS 机器不提供它,所以我必须从源代码构建它,然后在玩那些愚蠢的r-path
游戏时重建依赖于 OpenSSL 的每个库或程序。
在您的情况下,它看起来像 Apache、PHP、Drupal、MySQL、phpAdmin(当安全性受到关注时,有人真的会使用它吗 :) 和朋友。