我需要访问在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)

10-02 03:35
查看更多