首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(EC-)Diffie-Hellman的验证结果

(EC-)Diffie-Hellman的验证结果
EN

Cryptography用户
提问于 2021-08-19 13:43:36
回答 2查看 194关注 0票数 1

我收到了JSON的公钥。

例如,我有4个密钥:2个公钥和2个私钥。

代码语言:javascript
复制
public A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

private A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

public B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

private B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

我不能从用JSON接收的公钥A和私钥B进行ECDH交换。

如何验证:(公钥A+私钥B) == (公钥B+私钥A)?

EN

回答 2

Cryptography用户

回答已采纳

发布于 2021-08-27 14:50:40

,所以我就是这样解决问题的:

我的琴键:

代码语言:javascript
复制
public A : co2D0pNxZJIeQ4RZlCRJYBDzNXSLluETdztid0M+HGzN1uGJ4JWZsenjWgRrmkLh3yqHQqzOBMl/wHVH97A6+g==

private A : TXxii5Ka8LMvuc9arHu63qTmNKxGlgti+wpR3YhBGew=

public B : nUblC+OKdl94iBiWk0941wmYBiMt7C90CjOJPI2BPr8K7xGuC1XsR5DtwFCoM3Iew2BjBG+5SqrYwAPTJF7gdA==

private B : sm6V7+hChvkFSeLNoR+5tItiX8gH5tT47xBkFaV6SDU=

获取私钥的函数:

代码语言:javascript
复制
public static PrivateKey getPrivateKey(byte[] encodedPrivateKey) {
   BigInteger s = new BigInteger(1,encodedPrivateKey);
   ECNamedCurveParameterSpec ecCurve = ECNamedCurveTable.getParameterSpec("secp256r1");
   ECParameterSpec ecParameterSpec = new ECNamedCurveSpec("secp256r1", ecCurve.getCurve(), ecCurve.getG(), ecCurve.getN(), ecCurve.getH(), ecCurve.getSeed());
   ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(s, ecParameterSpec);
   try {
       KeyFactory keyFactory = KeyFactory.getInstance("EC");
       return keyFactory.generatePrivate(privateKeySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        return null;
   }
}

public static PublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidParameterSpecException {
   KeyFactory kf = KeyFactory.getInstance("EC");
   byte[] x = Arrays.copyOfRange(rawBytes, 0, rawBytes.length/2);
   byte[] y = Arrays.copyOfRange(rawBytes, rawBytes.length/2, rawBytes.length);
   ECPoint w = new ECPoint(new BigInteger(1,x), new BigInteger(1,y));
   return kf.generatePublic(new ECPublicKeySpec(w, ecParameterSpecForCurve(curveName)));
}

public static java.security.spec.ECParameterSpec ecParameterSpecForCurve(String curveName) throws NoSuchAlgorithmException, InvalidParameterSpecException {
   AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
   params.init(new ECGenParameterSpec(curveName));
   return params.getParameterSpec(ECParameterSpec.class);
}

我们需要通过字符串中的公钥/私有键创建2对密钥,并检查两者是否相等:

代码语言:javascript
复制
byte [] cle_publique_a_decode = Base64.getDecoder().decode(cle_publique_a);
byte [] cle_privee_a_decode = Base64.getDecoder().decode(cle_privee_a);
byte [] cle_publique_b_decode = Base64.getDecoder().decode(cle_publique_b);
byte [] cle_privee_b_decode = Base64.getDecoder().decode(cle_privee_b);

try {
     PublicKey PublicKeyA = rawToEncodedECPublicKey("secp256r1",cle_publique_a_decode);
     PublicKey PublicKeyB = rawToEncodedECPublicKey("secp256r1",cle_publique_b_decode);

     PrivateKey PrivateKeyA =  getPrivateKey(cle_privee_a_decode);
     PrivateKey PrivateKeyB =  getPrivateKey(cle_privee_b_decode);

     // Secret #1
     // PrivateKeyA + PublicKeyB = generateSecret
     KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyA);
     keyAgreement.doPhase(PublicKeyB, true);
     byte[] generateSecret = keyAgreement.generateSecret();
     String base64_generateSecret = Base64.getEncoder().encodeToString(generateSecret);

     // Secret #2
     // PrivateKeyB + PublicKeyA = generateSecret2
     KeyAgreement keyAgreement2 = KeyAgreement.getInstance("ECDH");
     keyAgreement.init(PrivateKeyB);
     keyAgreement.doPhase(PublicKeyA, true);
     byte[] generateSecret2 = keyAgreement.generateSecret();
     String base64_generateSecret2 = Base64.getEncoder().encodeToString(generateSecret);

     // compare 2 secrets
     // (public key A + private key B) == (public key B + private key A)
     if(base64_generateSecret.equals(base64_generateSecret2)){
          // Good : Secrets are same
          // continue..
     }
     else{
          // Not good : Secrets are differents
     }
}
catch{
     throw new IllegalArgumentException(e.getMessage(), e);
}

密钥是相等的,我可以开始加密。

票数 0
EN

Cryptography用户

发布于 2021-08-20 10:37:28

通常,(椭圆曲线) Diffie-Hellman计算的结果称为主秘密.此主键通常用作密钥派生函数(KDF)的输入键控材料(IKM)。使用KDF可以从主秘密派生多个密钥。你正在寻找的是所谓的“关键构象”。

确认对称密钥的方法有多种:

  1. 其中一个密钥可用作挑战响应协议的输入。质询响应协议是一种对称方法,用于验证实体是否有权访问正确的密钥。
  2. 另一种方法是使用密钥作为MAC的输入,而不是双方都知道的字符串。通过这种方式,MAC显示实体可以访问正确的密钥。例如,TLS (1.3)在握手的最后“完成”消息中对整个握手使用MAC : Finished: MAC ()用于整个握手。此消息提供密钥确认,将端点的标识绑定到交换的密钥,并且在PSK模式下还验证握手。第4.4.4节
  3. 您还可以想象,一方可以签署由此产生的秘密,并将签名发送给另一方。
  4. 最后,当第一个经过身份验证的消息从一方发送到另一方时,也可以隐式地执行结果密钥与由此产生的秘密的确认。但是,这通常是避免的,因为它意味着您无法区分数据传输和握手错误;因此,它可以在协议实现中发挥作用。

备注:

  • 如果您确认一个密钥,那么秘密和任何其他派生密钥的有效性也将被确认(除非实现错误)。
  • 可能是DH的(静态)公钥可以通过其他方式信任,在这种情况下,认证方可能不需要对结果的秘密进行额外的验证;只有未经身份验证的方才需要发送质疑响应、MAC或签名值。
票数 6
EN
页面原文内容由Cryptography提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://crypto.stackexchange.com/questions/93637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档