如何从 Java 中的 *pem 字符串生成 RSA 私钥

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18369330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:56:36  来源:igfitidea点击:

How to generate RSA Private key from *pem string in Java

javarsaprivate-keypemder

提问by Niklas

I want to generate the private key from a string(a .pemfile) in Java.

我想从.pemJava 中的字符串(文件)生成私钥。

private static final String test = "-----BEGIN RSA PRIVATE KEY-----\n" +
         "MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
         "-----END RSA PRIVATE KEY-----";

try {
    String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

    byte [] encoded = Base64.decode(privKeyPEM);

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey privKey = kf.generatePrivate(keySpec);
}
catch (Exception e) {
    e.printStackTrace();
}

The last line(generatePrivate function) is throwing this exception:

最后一行(generatePrivate 函数)抛出这个异常:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
    at java.security.KeyFactory.generatePrivate(Unknown Source)
    at Test.main(Test.java:52)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
    at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
    at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
    ... 3 more

If I change the private key to the value from a .derfile it works properly, but I need to generate the private key file from a .pemfile.

如果我将私钥更改为.der文件中的值,它可以正常工作,但我需要从.pem文件生成私钥文件。

I attached a screenshot of the bytes printed as string(once hard-coded with \n and once hard-coded without \n) and once from the file.

我附上了打印为字符串的字节的屏幕截图(一次是用 \n 硬编码,一次是不带 \n 硬编码),一次是从文件中打印出来的。

Bigger Image

更大的图像

Output

输出

The weird thing is that the output from the file is different to the output from the strings.

奇怪的是文件的输出与字符串的输出不同。

If I try to encode a .derfile with Base64, the result is different than the string in the .pemfile. Why is that so?

如果我尝试.der使用 Base64对文件进行编码,则结果与.pem文件中的字符串不同。为什么呢?

回答by H-Patel

You say that the last line is throwing exception, i.e.

你说最后一行是抛出异常,即

PrivateKey privKey = kf.generatePrivate(keySpec);

PrivateKey privKey = kf.generatePrivate(keySpec);

Above line works on keyspecs being set correct, i.e.

以上行适用于设置正确的keyspecs,即

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

So actual problem is with encoded bytes array. Have you done System.out after byte [] encoded = Base64.decode(privKeyPEM);and see what the output is.

所以实际的问题是编码的字节数组。你做了 System.out 之后byte [] encoded = Base64.decode(privKeyPEM);,看看输出是什么。

I understand that if the message is in MIME format, then after certain characters it appends a combination of carriage return and newline so the strings are not too long for e-mail system or wherever you are using it.

我知道如果消息是 MIME 格式,那么在某些字符之后它会附加回车符和换行符的组合,因此字符串对于电子邮件系统或您使用它的任何地方都不会太长。

The final String test has some '\n' in the original text which you use. You did get rid of other text in below line,

最后的 String 测试在您使用的原始文本中有一些 '\n'。您确实删除了下面一行中的其他文本,

String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

But, look at the string,

但是,看看字符串,

"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" +
// and so on
         "-----END RSA PRIVATE KEY-----";

it may have some more '\n' left which may result in some unwanted characters when you generate keyspec. Try more System.out and see what the encoded byte array is like and also before that check String privKeyPEM and see if any extra character is not left in it.

它可能还有一些 '\n' ,这可能会在您生成 keyspec 时导致一些不需要的字符。尝试更多 System.out 并查看编码的字节数组是什么样的,并在此之前检查 String privKeyPEM 并查看其中是否没有留下任何额外的字符。

Hope this hepls.

希望这有帮助。