我需要访问 SSL/TLS 握手期间交换的 SSL 服务器/客户端随机数,以便稍后在封装协议(protocol)中使用它们。
如何在 Java 中访问这些值?我查看了 SSLSocket.getHandshake()
但似乎没有公开这些值。
最佳答案
JSSE 中没有 API 调用可以让您直接访问它。
您可以通过-Djavax.net.debug=ssl
(“Client Nonce
”)轻松查看这一点,但无法从应用程序内部访问。
您可以通过对私有(private)成员进行反射来实现此目的,但是这通常是一个坏主意(就像在私有(private) API 上使用私有(private)成员进行反射一样)。这也很大程度上取决于您所使用的 Java 版本和实现。
Field handshakerField = sslSocket.getClass().getDeclaredField(
"handshaker");
handshakerField.setAccessible(true);
Object handShakerObj = handshakerField.get(sslSocket);
System.out.println(handShakerObj);
// Only start the handshake *after* you've got hold of the handshaker object,
// otherwise it will be null.
sslSocket.startHandshake();
Class<?> handshakerClass = Class.forName("sun.security.ssl.Handshaker");
Field clientRandomField = handshakerClass
.getDeclaredField("clnt_random");
clientRandomField.setAccessible(true);
Object clientRandomObj = clientRandomField.get(handShakerObj);
System.out.println(clientRandomObj);
Field randomBytesField = clientRandomObj.getClass().getDeclaredField(
"random_bytes");
randomBytesField.setAccessible(true);
byte[] randomBytesObj = (byte[])randomBytesField.get(clientRandomObj);
我不确定为什么你的封装协议(protocol)需要这个。这看起来根本不是一个好主意。目前尚不清楚这意味着增加什么样的安全性。如果您确实需要某种 SSL/TLS channel token ,那么使用 session ID 可能会更好(尽管这也不一定是个好主意)。
大多数 SSL/TLS 堆栈很可能不会让您掌握这一点。它的主要目的是生成 pre_master_secret
和 "the pre_master_secret should be deleted from memory once the master_secret has been computed." (according to the TLS specification) .
关于Java SSL 客户端/服务器随机值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24449351/