4

我需要使用 java 生成 PEM 格式的 RSA 和 DSA 密钥对(公钥和私钥)。我希望以这种格式打开公钥和私钥文件:

-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO 3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX 7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS j+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd OrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ 5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl FQIDAQAB -----结束公钥-----

我的公钥之前已经生成了我不想要的这种格式:

0×0 *†H†÷ 0×0 *†H†÷</p>

好的,这是我的密钥生成代码:

private static void createKey()
        throws Exception {

            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Password to encrypt the private key: ");
            String password = in.readLine();
            System.out.println("Generating an RSA keypair...");

            // Create an RSA key
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.genKeyPair();

            System.out.println("Done generating the keypair.\n");

            // Now we need to write the public key out to a file
            System.out.print("Public key filename: ");
            String publicKeyFilename = "C:/Users/Joe/Desktop/" + in.readLine();

            // Get the encoded form of the public key so we can
            // use it again in the future. This is X.509 by default.
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();

            // Write the encoded public key out to the filesystem
            FileOutputStream fos = new FileOutputStream(publicKeyFilename);
            fos.write(publicKeyBytes);
            fos.close();

            // Now we need to do the same thing with the private key,
            // but we need to password encrypt it as well.
            System.out.print("Private key filename: ");
            String privateKeyFilename = "C:/Users/Joe/Desktop/" + in.readLine();

            // Get the encoded form. This is PKCS#8 by default.
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

            // Here we actually encrypt the private key
            byte[] encryptedPrivateKeyBytes =
            passwordEncrypt(password.toCharArray(),privateKeyBytes);

            fos = new FileOutputStream(privateKeyFilename);
            fos.write(encryptedPrivateKeyBytes);
            fos.close();
        }

谢谢您的帮助..

4

2 回答 2

4

您可以使用充气城堡来代替手动生成 PEM 字符串:因为它是一个经过测试的库,您可以确定输出。以下代码在 Kotlin 中,但可以很容易地与 Java 语法一起使用:

        val gen = KeyPairGenerator.getInstance("RSA")
        gen.initialize(2048)
        val pair = gen.generateKeyPair()
        val privateKey: PrivateKey = pair.private
       
  
        val pemObject = PemObject("RSA PRIVATE KEY", privateKey.encoded)
        
        val byteStream = ByteArrayOutputStream()
        val pemWriter = PemWriter(OutputStreamWriter(byteStream))
        pemWriter.writeObject(pemObject)
        pemWriter.close();
        println(String(byteStream.toByteArray()))

于 2020-06-25T09:12:37.013 回答
3

也许有点晚了,但有我的解决方案。希望它可以帮助别人。

byte[] publicKeyBytes = keyPair.getPublic().getEncoded();

在这里,您正在获取密钥字节并直接写入文件。所以你得到了适当的结果——DER编码的文件。但是 PEM 是 Base64 编码格式,每 64 个符号和页眉/页脚都有换行符。

有实现此逻辑的代码:

String publicKeyContent = Base64.encode(publicKeyBytes);
String publicKeyFormatted = "-----BEGIN PUBLIC KEY-----" + System.lineSeparator();
for (final String row: 
        Splitter
            .fixedLength(64)
            .split(publicKeyContent)
    ) 
{
    publicKeyFormatted += row + System.lineSeparator();
}
publicKeyFormatted += "-----END PUBLIC KEY-----";

因此 publicKeyFormatted 将包含 PEM 编码的公钥字符串。

PS Splitter 是 Guava lib 中提供的一个类,但您可以通过简单的循环或其他方式拆分字符串。

于 2018-05-29T10:21:56.127 回答