【问题标题】:How to Generate an AES Key using a Local Private Key and a Remote Public Key in Java?如何在 Java 中使用本地私钥和远程公钥生成 AES 密钥?
【发布时间】:2025-12-05 08:55:01
【问题描述】:

您好,我正在阅读以下关于公钥密码学的*文章 Public Key Cryptography

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

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

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

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

【问题讨论】:

    标签: java encryption


    【解决方案1】:

    尝试KeyAgreement 和算法"DiffieHellman"。请注意,2048 位密钥大小需要 Java 8,Java 7 及更低版本卡在 1024 上(除非您安装 Bouncy Castle 提供程序)。

    或者您可以使用"ECDH" 算法,但要注意这需要一些学习曲线。

    【讨论】:

    • 谢谢我修好了,但是 KeyAgreement 类怎么没有 RSA 算法而只有 DiffieHellman 算法?
    • 您可以通过 Cipher 类使用 RSA 算法。在这种情况下,您只需加密要与公钥共享的密钥,然后使用(服务器的)私钥对其进行解密。然而,这不会给你完美的前向保密;即,如果 RSA 私钥已知,则可以读取使用会话密钥创建的密文。请注意 - 另一方面 - DH 可能不包含身份验证,因此通常容易受到中间人攻击。查看 TLS 以了解如何解决此问题。
    【解决方案2】:

    感谢 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");对于 KeyPairGenerator 的两个实例
    最近更新 更多