我想与服务器建立HTTPS连接,如果我正在使用的话 非短暂的DH密钥交换,我想知道什么参数 是为了那个连接。实际上,我真的不在乎它是不是 短暂与否。
我正在寻找的是能够建立连接然后发出警告 如果连接使用“弱”DH参数。这是我的事吗 可以在连接时检查?或者是DH参数的集合(或者更多 具体而言,由这些参数定义的那些参数的长度 密码套件本身?
例如,Qualys社区主题有一个插图 SSLLabs认为“弱”的密码套件(好吧,每个人都认为 他们很弱......他们只是有一个抱怨他们的公共工具): https://community.qualys.com/thread/14821
他们特别提到例如TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
这是密码套件0x9f并提及DH参数。是那些
参数的参数被烘焙到密码套件中(意思是它们是
总是 1024位)或者这是服务器的配置
那些密码套件因特定的DH参数选择而变弱?
在任何一种情况下,我都希望能够从中嗅到这些信息 如果可能的话连接。有谁知道这是否可以做到, 怎么样?
我已经编写了一些代码来尝试获取有关握手的信息,但是我一直在为我希望包含此数据的对象获取null
。
SSLSocketFactory sf = ...;
Socket sock = new Socket();
sock.connect(address, timeout);
SSLSocket socket = (SSLSocket)sf.createSocket(sock, host, port, true);
socket.startHandshake();
SSLSession sess = socket.getHandshakeSession();
我希望sess
此时会包含一些有关握手的有趣信息,但它是null
。 startHandshake
的javadoc表示它将在握手完成时通知事件侦听器。所以我尝试了这个:
SSLSocketFactory sf = ...;
Socket sock = new Socket();
sock.connect(address, timeout);
SSLSocket socket = (SSLSocket)sf.createSocket(sock, host, port, true);
socket.startHandshake();
// SSLSession sess = socket.getHandshakeSession();
SSLSession sess = socket.getSession(); // This forces the handshake to complete
sess = socket.getHandshakeSession();
...但此时sess
仍为null
。 “真正的”SSLSession确实存在,并提供有关连接的信息,但“握手会话”似乎总是null
。
所以我尝试写一个HandshakeCompletedListener
,我确实得到了一个SSLSession
,但它似乎与SSLSocket
已经得到的相同,所以“握手”会议似乎没有用。
如何从SSLSession
获取这些参数?
答案 0 :(得分:1)
这些参数是'参数烘焙到密码套件中(意味着它们总是1024位),或者这是服务器的配置,由于特定的DH参数选择,使得这些密码套件变弱?
不,这是协议的配置参数 。 Java的默认值为1024位,但可以使用系统属性jdk.tls.ephemeralDHKeySize
为JSSE(Java TLS实现)更改全局。最好在启动期间使用Java VM的-D选项设置它。
对于静态DH密钥对(用于身份验证),您必须查看DH证书。但我不认为你会找到任何人,每个人都使用RSA进行身份验证。
在任何一种情况下,如果可能的话,我希望能够从连接中嗅出该信息。有谁知道这是否可以做到,以及如何做到?
好吧,对于嗅探这样的工具,比如WireShark就足够了。毫无疑问,你可以解析TLS连接中的DH参数之类的东西(当然,如果它们首先使用的话)。
您还可以使用-Djavax.net.debug
对于Java应用程序/库,您可以查找密码套件,然后,如果它包含DHE_
,则查找上述系统属性(请记住其默认值)。
Java JSSE API并未考虑深度数据包检查。它(字面上)是服务器和客户端应用程序的面向服务的实现。虽然你当然可以使用OpenJDK代码本身(它是GPL' ed,对吗?)你最好使用单独的实现,可能还有更宽松的许可。
对于嗅探器,我宁愿使用C / C ++(或至少是C / C ++前端)而不是Java。
答案 1 :(得分:0)
对于大多数密码算法,长度由名称cypher名称确定,如此处How to get the actual block cipher key size for Java SSL connection _in code_?所述。 我建议通过仅选择您想要支持的密码来禁用这些密码,而不是在人们使用不安全的密码时警告他们。您可以在jvm级别或SSLSocket上执行此操作,例如
String pickedCipher[] ={"TLS_RSA_WITH_AES_128_CBC_SHA"};
socket.setEnabledCipherSuites(pickedCipher);
您也可以设置所需的密钥大小,请参阅此处 https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#customizing_dh_keys
您可以在https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html
中查看Java安全性中使用的默认值和类如果您感到好奇并希望更详细地研究这一点,我建议您打开ssl日志记录,如此处所述。