如何在Java中使用本地私钥和远程公钥生成AES密钥?

如何在Java中使用本地私钥和远程公钥生成AES密钥?,java,encryption,Java,Encryption,嗨,我在读维基百科上关于公钥密码的文章 我也看到了这张图片,它展示了如何使用您的私钥和其他人的公钥生成对称密钥密码。 我已经知道如何在双方之间交换公钥,但是我想知道是否可以使用Java编程语言在图中实现该过程 使用的私钥和公钥将使用RSA生成,要生成的密钥/共享密钥将是对称密码的对称密钥(我想使用AES-128) 我理解这背后的理论,但不确定如何正确地在Java中实现它,任何想法或帮助都将不胜感激:)尝试和算法。请注意,对于2048位密钥大小,您需要Java8,Java7及以下的密钥大小固定

嗨,我在读维基百科上关于公钥密码的文章

我也看到了这张图片,它展示了如何使用您的私钥和其他人的公钥生成对称密钥密码。

我已经知道如何在双方之间交换公钥,但是我想知道是否可以使用Java编程语言在图中实现该过程

使用的私钥和公钥将使用RSA生成,要生成的密钥/共享密钥将是对称密码的对称密钥(我想使用AES-128)

我理解这背后的理论,但不确定如何正确地在Java中实现它,任何想法或帮助都将不胜感激:)

尝试和算法。请注意,对于2048位密钥大小,您需要Java8,Java7及以下的密钥大小固定在1024位(除非您安装了提供程序)


或者你可以使用
“ECDH”
算法,但要注意这需要一点学习曲线。

感谢owlstead,我能够编写以下代码,生成RSA密钥,然后尝试使用DiffieHellman将私钥与相反的公钥链接在一起

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class AESKeGenFromRSA
{
public static void main(String[] args)
{
    try
    {
        // Generate RSA KeyPair for Alice
        Cipher alice_rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        // Get RSA KeyPairGenerator Object Instance
        KeyPairGenerator alice_gen = KeyPairGenerator.getInstance("RSA");
        // Generate RSA Assymetric KeyPair
        KeyPair alice_pair = alice_gen.generateKeyPair();
        // Extract Public Key
        PublicKey alice_pub = alice_pair.getPublic();
        // Extract Private Key
        PrivateKey alice_pvt = alice_pair.getPrivate();

        System.out.println();
        System.out.println("Alice Public: " + alice_pub);
        System.out.println();
        System.out.println("Alice Private: " + alice_pvt);

        // Generate RSA KeyPair for Bob
        Cipher bob_rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        // Get RSA KeyPairGenerator Object Instance
        KeyPairGenerator bob_gen = KeyPairGenerator.getInstance("RSA");
        // Generate RSA Assymetric KeyPair
        KeyPair bob_pair = bob_gen.generateKeyPair();
        // Extract Public Key
        PublicKey bob_pub = bob_pair.getPublic();
        // Extract Private Key
        PrivateKey bob_pvt = bob_pair.getPrivate();

        System.out.println();
        System.out.println("Bob Public: " + bob_pub);
        System.out.println();
        System.out.println("Bob Private: " + bob_pvt);

        // Create KeyAgreement for Alice
        KeyAgreement alice_agreement =     KeyAgreement.getInstance("DiffieHellman");
        alice_agreement.init(alice_pvt);
        alice_agreement.doPhase(bob_pub, true);
        byte[] alice_secret = alice_agreement.generateSecret();
        SecretKeySpec alice_aes = new SecretKeySpec(alice_secret, "AES");

        // Create KeyAgreement for Bob
        KeyAgreement bob_agreement = KeyAgreement.getInstance("DiffieHellman");
        bob_agreement.init(bob_pvt);
        bob_agreement.doPhase(alice_pub, true);
        byte[] bob_secret = bob_agreement.generateSecret();
        SecretKeySpec bob_aes = new SecretKeySpec(bob_secret, "AES");

        System.out.println();
        System.out.println(alice_aes.equals(bob_aes));
    }
    catch (NoSuchAlgorithmException e)
    {e.printStackTrace();}
    catch (NoSuchPaddingException e)
    {e.printStackTrace();}
    catch (InvalidKeyException e)
    {e.printStackTrace();}
}
}
这是我尝试运行程序时引发的异常。我理解为什么会发生这种情况,但我有点不确定如何解决它

java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
at javax.crypto.KeyAgreement.chooseProvider(KeyAgreement.java:398)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:464)
at javax.crypto.KeyAgreement.init(KeyAgreement.java:435)
at AESKeGenFromRSA.main(AESKeGenFromRSA.java:45)

PrivateKey对象似乎不是KeyAgreement.init(Key-Key)函数的有效参数,任何想法都将受到欢迎…

更不用说我通过更改KeyPairGenerator alice_gen=KeyPairGenerator.getInstance(“RSA”)解决了它;对于这个KeyPairGenerator alice_gen=KeyPairGenerator.getInstance(“DiffieHellman”);对于KeyPairGeneratorHanks的两个实例,我都修复了它,但为什么KeyAgreement类没有RSA算法,只有DiffieHellman算法?您可以使用
密码
类使用RSA算法。在这种情况下,只需使用公钥加密要共享的密钥,然后使用(服务器的)私钥解密即可。然而,这不会给你提供完美的前向保密;i、 e.如果已知RSA私钥,则可以读取使用会话密钥创建的密文。请注意,在另一方面,DH可能不包含身份验证,因此通常容易受到中间人攻击。看看TLS,看看如何解决这个问题。