Java Diffie-Hellman密钥交换

我正在尝试执行代码来执行Diffie-Hellman密钥交换。 我从在线示例中获取代码(忘记现在的位置)。 我不得不导入bouncycastle.jar,我假设它一直在执行。

stacktrace截图

我的代码:

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. } } 

这是导致问题的一行:

 KeyPair aPair = keyGen.generateKeyPair(); 

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

任何关于此的光线都将非常受欢迎。

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

你已经选择了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(); // ? ? // // OO // /|\ /|\ // / \ / \ // // ALICE BOB // 2. ------------------------------------------------------------------ // Alice and Bob generate public and private keys. alice.generateKeys(); bob.generateKeys(); // // OO // /|\ /|\ // / \ / \ // // 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); // // OO // /|\ /|\ // / \ / \ // // 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(); // // OO // /|\ /|\ // / \ / \ // // 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); // // OO // /|\ []--------------------------------> /|\ // / \ / \ // // 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

这个评论完全错了:

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

你所做的只是每次创建数字0x1234567890 。 它没有任何随意性。

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

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

而不是代码:

 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 

你需要使用:

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