如何使用 JVM 属性强制执行完美前向保密?

信息安全 tls 爪哇 前向保密
2021-08-14 03:15:19

根据这篇博文, Perfect Forward Secrecy (PFS) 由以下机构提供:

算法标准名称列表中TLS (传输级安全)开头的任何内容,后跟一种DHE(Diffie-Hellman Exchange)。

例如 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA、TLS_DHE_RSA_WITH_AES_128_CBC_SHA

我想通过在 java.security 文件中使用 Java 的 'jdk.tls.disabledAlgorithms' 属性来实现这一点。现在我对该属性具有以下值:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, MD5, DESede, DH keySize < 768, RSA keySize < 2048

以下是 TestSSLServer 的结果:

$ java -jar TestSSLServer.jar 127.0.0.1 9443
Supported versions: TLSv1.2
Deflate compression: no
Supported cipher suites (ORDER IS NOT SIGNIFICANT):
  TLSv1.2
     DHE_RSA_WITH_AES_128_CBC_SHA
     DHE_RSA_WITH_AES_256_CBC_SHA
     DHE_RSA_WITH_AES_128_CBC_SHA256
     DHE_RSA_WITH_AES_256_CBC_SHA256
     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
----------------------
Server certificate(s):
  xxxxx
----------------------
Minimal encryption strength:     strong encryption (96-bit or more)
Achievable encryption strength:  strong encryption (96-bit or more)
BEAST status: protected
CRIME status: protected

我仍然找不到一种机制来摆脱不提供 PFS 的套件。例如“DHE_RSA_WITH_AES_128_CBC_SHA”。

我们可以通过“jdk.tls.disabledAlgorithms”来完成这项工作吗?如果没有,是否还有其他 JVM 级别的机制?

更新

在@Steffen 确认我之前列出的所有密码都提供了 PFS 之后,我再次使用另一台服务器进行了测试,可以看到 RSA 被列为密钥交换算法。这次尝试使用 2 个工具 - 均由OWASP推荐

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, MD5, DESede, RSA keySize < 2048

注意:使用此属性设置 'DH keySize < 2048' 没有任何效果。我必须按照@Steffen 的建议使用系统属性“-Djdk.tls.ephemeralDHKeySize=2048”来增加 DH 密钥大小。

测试SSL服务器

Supported cipher suites (ORDER IS NOT SIGNIFICANT):
  TLSv1.2
     RSA_WITH_AES_128_CBC_SHA
     DHE_RSA_WITH_AES_128_CBC_SHA
     RSA_WITH_AES_256_CBC_SHA
     DHE_RSA_WITH_AES_256_CBC_SHA
     RSA_WITH_AES_128_CBC_SHA256
     RSA_WITH_AES_256_CBC_SHA256
     DHE_RSA_WITH_AES_128_CBC_SHA256
     DHE_RSA_WITH_AES_256_CBC_SHA256
     TLS_RSA_WITH_AES_128_GCM_SHA256
     TLS_RSA_WITH_AES_256_GCM_SHA384
     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

测试ssl.sh

Testing all 124 locally available ciphers against the server, ordered by encryption strength 

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.  Encryption Bits
------------------------------------------------------------------------
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 256   AESGCM    256       
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 256   AES       256       
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES       256       
 x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM    256       
 x6b     DHE-RSA-AES256-SHA256             DH 2048    AES       256       
 x39     DHE-RSA-AES256-SHA                DH 2048    AES       256       
 x9d     AES256-GCM-SHA384                 RSA        AESGCM    256       
 x3d     AES256-SHA256                     RSA        AES       256       
 x35     AES256-SHA                        RSA        AES       256       
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 256   AESGCM    128       
 xc027   ECDHE-RSA-AES128-SHA256           ECDH 256   AES       128       
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES       128       
 x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM    128       
 x67     DHE-RSA-AES128-SHA256             DH 2048    AES       128       
 x33     DHE-RSA-AES128-SHA                DH 2048    AES       128       
 x9c     AES128-GCM-SHA256                 RSA        AESGCM    128       
 x3c     AES128-SHA256                     RSA        AES       128       
 x2f     AES128-SHA                        RSA        AES       128       

我不能将 RSA 指定为禁用的密码,因为它也会从身份验证列表中删除 RSA - 不仅是密钥交换。

如何通过 JVM 级别的属性/配置实现 PFS?我正在使用 Java 1.8.0_111 在同一台机器上运行客户端和服务器

2个回答

可以通过列出 Qualys SSLtest 在 中称为“弱”的所有密码套件来强制执行前向jdk.tls.disabledAlgorithms保密java.security请参阅 Bart Mortelmans 在https://stackoverflow.com/questions/41237075/disabling-specific-weak-ciphers-and-enforcing-perfect-forward-secrecy-using-jvm的回答。

我最终得到了这个:

[root@dolphin12 ~]# grep ^jdk.tls.dis -A6 /usr/lib/jvm/java/jre/lib/security/java.security
jdk.tls.disabledAlgorithms=SSLv2Hello, SSLv3, TLSv1, TLSv1.1, DES, DESede, RC4, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, DES40_CBC, RC4_40, \
    TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, \
    TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, \
    TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, \
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, \
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA

那里可能有一些低效、不必要或双重的东西,但它给了我 A 级,它也阻止了 Chrome 安全工具抱怨AES_256_CBC with HMAC-SHA1,它称之为“过时的密码”。

您提供的所有密码套件都提供 PFS,因为这些都是 DHE 和 ECDHE 密码套件。DHE_RSA_WITH_AES_128_CBC_SHA 中的 RSA 仅指定 RSA 用于身份验证。但是 DHE 用于密钥交换,这是 PFS 的重要部分。

除此之外:您仍然允许 768 位的 DH 密钥大小,这被认为是弱的。DH 至少使用 1024 位,但最好使用 2048。