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

时间:2013-08-21 23:33:52

标签: java rsa private-key pem der

我想用Java中的字符串(.pem文件)生成私钥。

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();
}

最后一行(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

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

我附上了以字符串形式打印的字节的屏幕截图(一次用\ n硬编码,一次硬编码,没有\ n),一次从文件中删除。

Bigger Image

Output

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

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

1 个答案:

答案 0 :(得分:1)

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

PrivateKey privKey = kf.generatePrivate(keySpec);

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

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

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

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

最终的String测试在您使用的原始文本中有一些'\ n'。你确实摆脱了下面的其他文字,

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

但是,看看字符串,

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

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

希望这一点。