BouncyCastle ECDH密钥协议失败 [英] BouncyCastle ECDH Key Agreement Fails

查看:243
本文介绍了BouncyCastle ECDH密钥协议失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用BouncyCastle API实现了椭圆曲线Diffie Hellman加密。但是,关键协议似乎并未正常运行。

I implemented a Elliptic Curve Diffie Hellman cryptography using BouncyCastle API. But, it doesn't seem that the key agreement is working properly. It prints false.

我在哪里做错了?谢谢。

Where did I do wrong? Thank you.

ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("B-571");

    KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC");

    g.initialize(ecSpec, new SecureRandom());

    KeyPair aKeyPair = g.generateKeyPair();

    KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "BC");

    aKeyAgree.init(aKeyPair.getPrivate());

     KeyPair bKeyPair = g.generateKeyPair();

    KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDH", "BC");

    bKeyAgree.init(bKeyPair.getPrivate());

    //
    // agreement
    //
    aKeyAgree.doPhase(bKeyPair.getPublic(), true);
    bKeyAgree.doPhase(aKeyPair.getPublic(), true);

    byte[] aSecret = aKeyAgree.generateSecret();
    byte[] bSecret = bKeyAgree.generateSecret();

    System.out.println(aSecret);
    System.out.println(bSecret);
    if (aSecret.equals(bSecret)){
        return true;
    } else { return false; }


推荐答案

当我用Bouncy测试时,它确实可以正常工作城堡1.49。但是,您正在使用错误的方法进行比较。

It does work correctly, when I tested with Bouncy Castle 1.49. However, you're comparing using the wrong method.

  • If you need time-constant comparison, use MessageDigest.isEqual.
  • If you don't need time-constant comparison, use Arrays.equals.

要打印出字节数组的内容,请使用Arrays.toString

To print out the contents of the byte arrays, use Arrays.toString:

System.out.println(Arrays.toString(aSecret));
System.out.println(Arrays.toString(bSecret));
return MessageDigest.isEqual(aSecret, bSecret);






编辑:OP要求我解释一下时间常数比较的意思是这样,这里是这样:无论两个字符串是否匹配,时间常数比较都会花费相同的时间运行。如果两个字符串不匹配,那么非时间常数的比较通常会花费较少的时间,运行时间取决于不匹配的位置:当发现第一个不匹配时,比较将停止。


The OP asked me to explain what "time-constant comparison" means, so here goes: a time-constant comparison takes the same amount of time to run, whether or not the two strings match. A non-time-constant comparison will usually take less time to run if the two strings have a mismatch, and the runtime depends on where the mismatch is: the comparison stops when the first mismatch is found.

是否需要进行时间常数比较取决于您是否具有定时预言。也就是说,比较所需的时间长短会为攻击者提供有用的信息吗?

Whether you need a time-constant comparison or not depends on whether you have a timing oracle. That is, will the length of time the comparison took will give an attacker useful information?

以下是定时预告片的示例:假设您是一个发送警告的Web服务器。 Cookie到浏览器。您不希望用户篡改cookie,因此请附加cookie内容的HMAC:

Here's an example of a timing oracle: suppose you're a web server sending a cookie to a browser. You don't want the user to tamper with the cookie, so you attach an HMAC of the cookie's contents:

cookie_to_send = hmac(cookie) + ":" + cookie

现在,当浏览器将cookie发送回给您时,您重新计算HMAC并查看是否匹配:

Now, when the browser sends the cookie back to you, you recompute the HMAC and see if it matches:

mac, cookie = received_cookie.split(":")
compare(mac, hmac(cookie))

如果比较失败( mac hmac(cookie))不匹配,则您拒绝该请求。

And if the comparison fails (the mac doesn't match the hmac(cookie)), then you reject the request.

在上面的 compare 操作中,这是一个恒定时间比较非常重要。否则,攻击者可以查看您的服务器拒绝请求所花费的时间,并以此推断出预期的HMAC值。这是因为比较的一个组成部分(cookie中的HMAC值,在第一个之前)由攻击者控制,并且攻击者可以逐字节调整其值。 -byte来查看每次拒绝需要多长时间。

In that compare operation above, it is very, very important that this be a constant-time comparison. Otherwise, the attacker can look at how long your server took to reject the request, and use that to deduce what the expected HMAC value is. This is because one component of the comparison (the HMAC value in the cookie, before the first :) is controlled by the attacker, and the attacker can adjust its value byte-by-byte to see how long the rejection takes each time.

在您的情况下,您的字节数组(即比较)是由 generateSecret()生成的,这向我表明,它不受攻击者控制。因此,从表面上看,似乎并没有必要进行时间常数比较。但是我不是安全专家,所以我不确定。使用时间常数比较总是安全的(但是如果比较长的话可能会很慢),所以如果我不确定,那就是我的建议。

In your case, your byte arrays (that you're comparing) are generated from generateSecret(), which suggests to me that it's not attacker-controlled. So, on the surface, it doesn't appear as if a time-constant comparison is necessary. But I'm not a security expert, so I don't know for sure. It's always safe (but can be slow, if the strings being compared are long) to use a time-constant comparison, so if at all unsure, that's what I suggest.

这篇关于BouncyCastle ECDH密钥协议失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆