我需要访问在SSL / TLS握手期间交换的SSL服务器/客户端随机数,以便以后可以在封装协议中使用它们。
如何在Java中访问这些值?我看过SSLSocket.getHandshake()
,但这似乎没有暴露这些值。
最佳答案
JSSE中没有API调用可让您直接访问它。
您可以通过-Djavax.net.debug=ssl
(“ Client Nonce
”)轻松查看此内容,但是无法从应用程序内部访问。
您可以通过对私有成员进行反射来做到这一点,但这通常是一个坏主意(就像在私有API上使用私有成员进行反射的任何使用一样)。这也将非常取决于您所使用的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);
我不确定为什么您的封装协议会需要这个。这似乎根本不是一个好主意。目前尚不清楚这意味着要添加哪种安全性。如果您确实想使用某种SSL / TLS通道令牌,则使用会话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)。