Java Diffie-Hellman 密钥交换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22479508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:59:22  来源:igfitidea点击:

Java Diffie-Hellman key exchange

javabouncycastlediffie-hellman

提问by Simon.

I'm trying to execute code to perform the Diffie-Hellman key exchange. I sourced the code from an example online (forget where now). I had to import the bouncycastle.jar, which I assumed worked up until execution.

我正在尝试执行代码来执行 Diffie-Hellman 密钥交换。我从在线示例中获取代码(现在忘记在哪里了)。我不得不导入 bouncycastle.jar,我认为它在执行之前一直有效。

stacktrace screenshot

堆栈跟踪截图

my code:

我的代码:

package testproject;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.KeyAgreement;
import javax.crypto.spec.DHParameterSpec;

public class KeyGen {

  private static BigInteger g512 = new BigInteger("1234567890", 16);
  //generates a random, non-negative integer for Base

  private static BigInteger p512 = new BigInteger("1234567890", 16);
  //generates a random, non-negative integer for Prime

  public static void main(String[] args) throws Exception {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    DHParameterSpec dhParams = new DHParameterSpec(p512, g512);
    //Specify parameters to use for the algorithm
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC");
    //Define specific algorithm to use "diffie-hellman", with provider "bc"

    keyGen.initialize(dhParams, new SecureRandom());
    //initialize with parameters & secure random seed

    KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC");
    //define algorithm for A's key agreement
    KeyPair aPair = keyGen.generateKeyPair();
    //generate keyPair for A

    KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", "BC");
    //define algorithm for B's key agreement
    KeyPair bPair = keyGen.generateKeyPair();
    //generate keyPair for B

    aKeyAgree.init(aPair.getPrivate());
    //initialize A's keyAgreement with A's private key
    bKeyAgree.init(bPair.getPrivate());
    //initialize B's keyAgreement with B's private key

    aKeyAgree.doPhase(bPair.getPublic(), true);
    //do last phase of A's keyAgreement with B's public key
    bKeyAgree.doPhase(aPair.getPublic(), true);
    //do last phase of B's keyAgreement with A's public key

    MessageDigest hash = MessageDigest.getInstance("SHA1", "BC");

    System.out.println(new String(hash.digest(aKeyAgree.generateSecret())));
    //generate secret key for A, hash it.
    System.out.println(new String(hash.digest(bKeyAgree.generateSecret())));
    //generate secret key for B, hash it.
  }
}

This is the line causing the problem:

这是导致问题的行:

KeyPair aPair = keyGen.generateKeyPair();

I'm confused as to what the error is, as I've found each of the methods it's returning 'unknown source' for.

我对错误是什么感到困惑,因为我发现它返回“未知来源”的每个方法。

Any light shed on this would be much appreciated.

对此的任何启发将不胜感激。

Continued(Edit): Java - Diffie-Hellman Encryption - Wrong Output

续(编辑): Java - Diffie-Hellman 加密 - 错误的输出

回答by Alex Wittig

This comment is simply wrong:

这个评论是完全错误的:

private static BigInteger g512 = new BigInteger("1234567890", 16);
//generates a random, non-negative integer for Base

All you are doing there is creating the number 0x1234567890every time. There is nothing random about it.

您在那里所做的就是0x1234567890每次都创建数字。没有什么是随机的。

It looks like you copied from http://www.java2s.com/Tutorial/Java/0490__Security/DiffieHellmanKeyAgreement.htm. As this answeragrees, the code there does not make sense.

看起来您是从http://www.java2s.com/Tutorial/Java/0490__Security/DiffieHellmanKeyAgreement.htm复制的。正如这个答案所同意的那样,那里的代码没有意义。

You could try the actual key exchange exampleon that site.

您可以在该站点上尝试实际的密钥交换示例

回答by Жека М

Instead of the code:

而不是代码:

private static BigInteger g512 = new BigInteger("1234567890", 16);
   //generates a random, non-negative integer for Base

   private static BigInteger p512 = new BigInteger("1234567890", 16);
   //generates a random, non-negative integer for Prime

you need to use:

你需要使用:

// The base used with the SKIP 1024 bit modulus
private static final BigInteger g512 = BigInteger.valueOf(2);

// The 1024 bit Diffie-Hellman modulus values used by SKIP
private static final byte skip1024ModulusBytes[] = { (byte) 0xF4,
    (byte) 0x88, (byte) 0xFD, (byte) 0x58, (byte) 0x4E, (byte) 0x49,
    (byte) 0xDB, (byte) 0xCD, (byte) 0x20, (byte) 0xB4, (byte) 0x9D,
    (byte) 0xE4, (byte) 0x91, (byte) 0x07, (byte) 0x36, (byte) 0x6B,
    (byte) 0x33, (byte) 0x6C, (byte) 0x38, (byte) 0x0D, (byte) 0x45,
    (byte) 0x1D, (byte) 0x0F, (byte) 0x7C, (byte) 0x88, (byte) 0xB3,
    (byte) 0x1C, (byte) 0x7C, (byte) 0x5B, (byte) 0x2D, (byte) 0x8E,
    (byte) 0xF6, (byte) 0xF3, (byte) 0xC9, (byte) 0x23, (byte) 0xC0,
    (byte) 0x43, (byte) 0xF0, (byte) 0xA5, (byte) 0x5B, (byte) 0x18,
    (byte) 0x8D, (byte) 0x8E, (byte) 0xBB, (byte) 0x55, (byte) 0x8C,
    (byte) 0xB8, (byte) 0x5D, (byte) 0x38, (byte) 0xD3, (byte) 0x34,
    (byte) 0xFD, (byte) 0x7C, (byte) 0x17, (byte) 0x57, (byte) 0x43,
    (byte) 0xA3, (byte) 0x1D, (byte) 0x18, (byte) 0x6C, (byte) 0xDE,
    (byte) 0x33, (byte) 0x21, (byte) 0x2C, (byte) 0xB5, (byte) 0x2A,
    (byte) 0xFF, (byte) 0x3C, (byte) 0xE1, (byte) 0xB1, (byte) 0x29,
    (byte) 0x40, (byte) 0x18, (byte) 0x11, (byte) 0x8D, (byte) 0x7C,
    (byte) 0x84, (byte) 0xA7, (byte) 0x0A, (byte) 0x72, (byte) 0xD6,
    (byte) 0x86, (byte) 0xC4, (byte) 0x03, (byte) 0x19, (byte) 0xC8,
    (byte) 0x07, (byte) 0x29, (byte) 0x7A, (byte) 0xCA, (byte) 0x95,
    (byte) 0x0C, (byte) 0xD9, (byte) 0x96, (byte) 0x9F, (byte) 0xAB,
    (byte) 0xD0, (byte) 0x0A, (byte) 0x50, (byte) 0x9B, (byte) 0x02,
    (byte) 0x46, (byte) 0xD3, (byte) 0x08, (byte) 0x3D, (byte) 0x66,
    (byte) 0xA4, (byte) 0x5D, (byte) 0x41, (byte) 0x9F, (byte) 0x9C,
    (byte) 0x7C, (byte) 0xBD, (byte) 0x89, (byte) 0x4B, (byte) 0x22,
    (byte) 0x19, (byte) 0x26, (byte) 0xBA, (byte) 0xAB, (byte) 0xA2,
    (byte) 0x5E, (byte) 0xC3, (byte) 0x55, (byte) 0xE9, (byte) 0x2F,
    (byte) 0x78, (byte) 0xC7 };

// The SKIP 1024 bit modulus
private static final BigInteger p512 = new BigInteger(1, skip1024ModulusBytes);

回答by F?rat Kü?üK

You already preferred bouncycastle version. But I implemented a little helloworld version of it for learning purposes. Maybe it can be helpful for those who simply wants to use Diffie-Hellman in pure Java without dependencies:

您已经首选 bouncycastle 版本。但是为了学习目的,我实现了它的一个小的 helloworld 版本。也许它对那些只想在没有依赖项的纯 Java 中使用 Diffie-Hellman 的人有所帮助:

// 1. ------------------------------------------------------------------
// This is Alice and Bob
// Alice and Bob want to chat securely. But how?

final Person alice = new Person();
final Person bob   = new Person();

//    ?                                        ?
//
//    O                                        O
//   /|\                                      /|\
//   / \                                      / \
//
//  ALICE                                     BOB

// 2. ------------------------------------------------------------------
// Alice and Bob generate public and private keys.

alice.generateKeys();
bob.generateKeys();

//
//    O                                        O
//   /|\                                      /|\
//   / \                                      / \
//
//  ALICE                                     BOB
//  _ PUBLIC KEY                              _ PUBLIC KEY
//  _ PRIVATE KEY                             _ PRIVATE KEY

// 3. ------------------------------------------------------------------
// Alice and Bob exchange public keys with each other.

alice.receivePublicKeyFrom(bob);
bob.receivePublicKeyFrom(alice);

//
//    O                                        O
//   /|\                                      /|\
//   / \                                      / \
//
//  ALICE                                     BOB
//  + public key                              + public key
//  + private key                             + private key
//  _ PUBLIC KEY <------------------------->  _ PUBLIC KEY

// 4. ------------------------------------------------------------------
// Alice generates common secret key via using her private key and Bob's public key.
// Bob generates common secret key via using his private key and Alice's public key.
// Both secret keys are equal without TRANSFERRING. This is the magic of Diffie-Helman algorithm.

alice.generateCommonSecretKey();
bob.generateCommonSecretKey();

//
//    O                                        O
//   /|\                                      /|\
//   / \                                      / \
//
//  ALICE                                     BOB
//  + public key                              + public key
//  + private key                             + private key
//  + public key                              + public key
//  _ SECRET KEY                              _ SECRET KEY

// 5. ------------------------------------------------------------------
// Alice encrypts message using the secret key and sends to Bob

alice.encryptAndSendMessage("Bob! Guess Who I am.", bob);

//
//    O                                        O
//   /|\ []-------------------------------->  /|\
//   / \                                      / \
//
//  ALICE                                     BOB
//  + public key                              + public key
//  + private key                             + private key
//  + public key                              + public key
//  + secret key                              + secret key
//  + message                                 _ MESSAGE

// 6. ------------------------------------------------------------------
// Bob receives the important message and decrypts with secret key.

bob.whisperTheSecretMessage();

//
//    O                     (((   (((   (((   \O/   )))
//   /|\                                       |
//   / \                                      / \
//
//  ALICE                                     BOB
//  + public key                              + public key
//  + private key                             + private key
//  + public key                              + public key
//  + secret key                              + secret key
//  + message                                 + message

https://github.com/firatkucuk/diffie-hellman-helloworld

https://github.com/firatkucuk/diffie-hellman-helloworld