diffiehellman java,确定Diffie-Hellman“参数”。 Java中TLS握手的长度

I'd like to make an HTTPS connection to a server and, if I'm using

non-ephemeral DH key exchange, I'd like to know what the parameters

are for that connection. Actually, I don't really care if it's

ephemeral or not.

What I'm looking for is the ability to make a connection and then warn

if the connection is using "weak" DH parameters. Is that something I

can check at connection-time? Or is the set of DH parameters (or, more

specifically, the length of those parameters, in bits) defined by

the cipher suite itself?

For example, the Qualys community thread has an illustration of the

cipher suites that SSLLabs considers "weak" (well, everyone considers

them weak... they just have a public tool which complains about them):

https://community.qualys.com/thread/14821

They specifically mention e.g. TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

which is cipher suite 0x9f and mention the DH parameters. Are those

parameters' parameters baked-into the cipher suite (meaning they are

always 1024-bit) or is this a configuration of the server that makes

those cipher suites weak due to the specific DH parameter choice?

In either case, I'd like to be able to sniff that information from the

connection if at all possible. Does anyone know if this can be done,

and how?

I've written some code to attempt to get this information about the handshake, but I keep getting null for the object I was hoping would contain this data.

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();

I was hoping that sess at this point would contain some interesting information about the handshake, but it's null. The javadoc for startHandshake indicates that it will notify an event listener when the handshake is completed. So I tried this:

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();

... but sess is still null at this point. The "real" SSLSession does exist and gives me information about the connection, but the "handshake session" seems to always be null.

So I tried writing an HandshakeCompletedListener, and I do in fact get an SSLSession, but it appears to be the same one that I can get from the SSLSocket already, so the "handshake" session seems to be unhelpful.

How can I get those parameters from the SSLSession?

解决方案

Are those parameters' parameters baked-into the cipher suite (meaning they are always 1024-bit) or is this a configuration of the server that makes those cipher suites weak due to the specific DH parameter choice?

No, this is a configuration parameter for the protocol. There is a default of 1024 bits for Java but that may be changed globally for JSSE (the Java TLS implementation) using a system property: jdk.tls.ephemeralDHKeySize. Best set this during startup with a -D option for the Java VM.

For static DH key pairs (that are used for authentication) you would have to look into the DH certificate. But I don't think you'll find any, everybody uses RSA for authentication.

In either case, I'd like to be able to sniff that information from the connection if at all possible. Does anyone know if this can be done, and how?

Well, for sniffing tools such as WireShark would suffice. Undoubtedly you can parse things like DH parameters from a TLS connection (if they are used in the first place of course).

You can also debug connections using -Djavax.net.debug

For Java applications / libraries you could look up the cipher suite and then, if it contains DHE_ look up the aforementioned system property (keeping in mind its default values).

The Java JSSE API was not written with deep packet inspection in mind. It's (literally) a service oriented implementation for servers and client applications. Although you could of course use the OpenJDK code itself (it's GPL'ed, right?) you are better off using a separate implementation, possibly with an even more permissive license.

For a sniffer however I would rather use C/C++ (or at least a C/C++ frontend) than Java.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Diffie-Hellman算法是一种密钥交换协议,它可以在不安全的通信信道上协商出一个共享的密钥。下面是用JAVA实现Diffie-Hellman算法的示例代码: ```java import java.math.BigInteger; import java.security.SecureRandom; public class DiffieHellman { private static final BigInteger P = new BigInteger("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" + "FFFFFFFFFFFFFFFF", 16); private static final BigInteger G = BigInteger.valueOf(2); public static void main(String[] args) { // Alice and Bob generate their private keys BigInteger a = generatePrivateKey(); BigInteger b = generatePrivateKey(); // Alice and Bob calculate their public keys BigInteger A = calculatePublicKey(a); BigInteger B = calculatePublicKey(b); // Alice and Bob exchange their public keys BigInteger secretA = calculateSecretKey(a, B); BigInteger secretB = calculateSecretKey(b, A); // Check if the shared secrets are equal if (secretA.equals(secretB)) { System.out.println("Shared secret: " + secretA); } else { System.out.println("Error: shared secrets do not match"); } } private static BigInteger generatePrivateKey() { SecureRandom random = new SecureRandom(); return new BigInteger(256, random); } private static BigInteger calculatePublicKey(BigInteger privateKey) { return G.modPow(privateKey, P); } private static BigInteger calculateSecretKey(BigInteger privateKey, BigInteger publicKey) { return publicKey.modPow(privateKey, P); } } ``` 该示例代码实现了Diffie-Hellman算法的基本步骤: 1. Alice和Bob生成各自的私钥a和b; 2. Alice和Bob分别使用自己的私钥计算出公钥A和B; 3. Alice和Bob交换公钥; 4. Alice使用自己的私钥和Bob的公钥计算出共享密钥; 5. Bob使用自己的私钥和Alice的公钥计算出共享密钥; 6. Alice和Bob比较计算出的共享密钥是否相同,如果相同则表示密钥交换成功。 在实际应用,需要注意的是,为了保证安全性,需要选择足够大的素数P和生成元G,以及随机的私钥a和b。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值