如何在Java中为私有密钥和公共密钥组合共享密钥

时间:2012-01-25 11:20:56

标签: java cryptography public-key-encryption

我正在阅读有关公钥公钥加密(http://en.wikipedia.org/wiki/Public-key_cryptography)的维基百科,其中包含:

  

在Diffie-Hellman密钥交换方案中,每一方生成公钥/私钥对并分发公钥...在获得彼此公钥的真实副本后,Alice和Bob可以离线计算共享密钥。例如,共享密钥可以用作对称密码的密钥。

我想知道如何在Java中实现这一目标?即,如果给出一个任意的公钥和一个任意的私钥,如何从中产生一个共享秘密?

更清楚地说明:

Alice拥有公钥/私钥对 key_pair_alice

Bob有公钥/私钥对 key_pair_bob

假设我的理解是正确的,那么应该有一个方法 combine_keys(),以便:

combine_keys(key_pair_alice.private, key_pair_bob.public) == 
    combine_keys(key_pair_alice.public, key_pair_bob.private) 

我的问题是如何在Java中实现 combine_keys()方法。

感谢。

5 个答案:

答案 0 :(得分:3)

经过一些研究,我使用Java的加密包来提出解决方案。

 public static void main(String[] args) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator
    .getInstance("DH");
paramGen.init(1024);

// Generate the parameters
AlgorithmParameters params = paramGen.generateParameters();
DHParameterSpec dhSpec = (DHParameterSpec) params
    .getParameterSpec(DHParameterSpec.class);

keyGen.initialize(dhSpec);

KeyPair alice_key = keyGen.generateKeyPair();
KeyPair bob_key = keyGen.generateKeyPair();

SecretKey secret_alice = combine(alice_key.getPrivate(),
    bob_key.getPublic());

SecretKey secret_bob = combine(bob_key.getPrivate(),
    alice_key.getPublic());

System.out.println(Arrays.toString(secret_alice.getEncoded()));
System.out.println(Arrays.toString(secret_bob.getEncoded()));
}

private static SecretKey combine(PrivateKey private1,
    PublicKey public1)  {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(private1);
ka.doPhase(public1, true);
SecretKey secretKey = ka.generateSecret("DES");
return secretKey;
}

最后的sysout显示alice和bob现在共享相同的秘密。

答案 1 :(得分:2)

你似乎误解了这篇文章。不从私有/公共密钥对生成共享秘密。它是一方拥有的任意数据(或者例如在对称密码的密钥的情况下生成),并通过不安全的数据传输系统(例如,电子邮件,大多数网络协议等)与另一方共享。使用其他公钥加密并使用自己的私钥进行签名。共享秘密的生成算法可以是任意的,并且不依赖于私钥/公钥。它们只是用来传达双方之间的秘密。

答案 2 :(得分:1)

公钥和私钥从不是任意的,而是一起生成的,即它们是密钥对。然后,您可以使用私钥解密使用公钥加密的邮件,或使用私钥对邮件进行签名。 Diffie-Hellman的想法是使用通信伙伴的公钥加密对称密钥,以便可以安全地传输。通信伙伴可以使用她的私钥解密对称密钥。这样,两个通信伙伴共享一个共同的对称密钥,它们可以用于对称加密。

有一个与此相关的java包,javax.crypto,但我没有使用它的经验。也许API可以帮助你。

答案 3 :(得分:1)

  

假设我的理解是正确的,那么应该有一种方法   combine_keys()

当然有办法。这种方式众所周知Diffie-Hellman's method。 Diffie-Hellman的Java实现很多。例如look here。您的combine()方法归于sharedKey

答案 4 :(得分:0)

  

给定一个任意公钥和一个任意私钥,如何从中生成一个共享密钥?

假设具有公钥的一方具有秘密(例如由加密字符串伪随机数生成器生成的一系列位)。

  1. 使用所选算法和公钥加密秘密。

  2. 它使用私钥将加密的秘密发送给聚会。

  3. 拥有私钥的一方解密加密的秘密,双方共享秘密。

  4. 重要的是,只有拥有私钥的一方才能进行解密。因此,如果私钥没有泄露且算法没有被删除,则上述序列也保证即使第三方拦截加密的秘密,秘密仍然是秘密。

      

    我想知道如何在Java中实现这个目标?

    Java中存在现有的实现。如果你不能使用其中一个,那么你可以从头开始实现一个已发布的算法,并用它来实现上面的共享秘密程序。

    您可能需要比维基百科更好的信息来源。有关于这个主题的教科书......