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

如何在Java中为共享密钥组合私钥和公钥,java,cryptography,public-key-encryption,Java,Cryptography,Public Key Encryption,我正在阅读维基百科中关于公钥密码术()的内容,其中写道: 在Diffie–Hellman密钥交换方案中,各方生成一对公钥/私钥,并分发公钥。。。在获得彼此公钥的真实副本后,Alice和Bob可以离线计算共享密钥。例如,共享密钥可以用作对称密码的密钥 我想知道如何在Java中实现这一点?i、 例如,给定任意公钥和任意私钥,如何从中生成共享密钥 更清楚地说: Alice有一个公钥/私钥对key\u pair\u Alice Bob有一个公钥/私钥对key\u pair\u Bob 假设我的理解是正确

我正在阅读维基百科中关于公钥密码术()的内容,其中写道:

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

我想知道如何在Java中实现这一点?i、 例如,给定任意公钥和任意私钥,如何从中生成共享密钥

更清楚地说:

Alice有一个公钥/私钥对key\u pair\u Alice

Bob有一个公钥/私钥对key\u pair\u Bob

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

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


谢谢。

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

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

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

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

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

  • 它使用所选择的算法和公钥对秘密进行加密

  • 它将加密的秘密发送给具有私钥的一方

  • 拥有私钥的一方解密加密的秘密,双方共享该秘密

  • 重要的是,只有拥有私钥的一方才能进行解密。因此,如果私钥没有泄漏并且算法没有崩溃,上述序列还保证即使第三方截获加密的秘密,该秘密仍然是秘密

    我想知道如何在Java中实现这一点

    Java中有一些现有的实现。如果您不能使用其中一个,那么您可以从头实现一个已发布的算法,并使用它来实现上述共享秘密过程

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

    假设我的理解是正确的,应该有一个方法 组合_键()


    当然有办法。这条路是众所周知的。Diffie Hellman有很多Java实现。例如。您的combine()方法被称为sharedKey

    经过一些研究,我使用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现在共享同一个秘密。

    可能重复感谢您的提问和稍后的研究-基本上,大多数人认为“RSA约束”中的这一酷属性通常不可能,因此误解了这个问题…嗯,我不太确定这一点。在文章中,它说共享秘密由双方离线计算。通过离线,我认为这意味着双方不需要进一步交流?图中清楚地显示了它结合了两个密钥来生成一个共享秘密。请看:扩展图显示双方需要就“公共涂料”达成一致。在这种情况下,最终的密钥实际上是离线计算的。如果要实现此算法,请查看本文中的示例。你可以自由地使用任何适合该方案的算法来计算公共密钥,因此没有唯一的实现方法。PS:我还认为Diffie Hellman在公钥密码学文章中的提及有点误导,因为它实际上是一种只使用私钥而不使用公钥的不同方案。你可以将它用于公钥和私钥,但我看不出有什么意义,因为当你使用公钥和私钥时,不需要计算共享密钥。我也在尝试做同样的事情,但我认为这段代码可能不太正确-看起来alice_key和bob_key被初始化为同一个密钥对-因此两者“组合”为相同的值。
     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;
    }