2013-08-21 77 views
6

我想用Java中的字符串(.pem文件)生成私鑰。如何從Java中的* pem字符串生成RSA私鑰

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文件中的字符串不同。爲什麼?

+0

您是否找到答案? –

+0

@SankarP不真的。 – Niklas

+0

好的。我找到了解決方案。以「----- BEGIN RSA PRIVATE KEY」開頭的密鑰是pkcs1編碼的文件。除非您使用像BouncyCastle這樣的外部庫,否則Java不支持此pkcs1編碼。昨天遇到同樣的問題,大約8小時後,我找到了解決方案。如果您使用pkcs8編碼私鑰,它將以「--- BEGIN PRIVATE KEY ---」開始,這將由stock java處理。 HTH。 –

回答

1

你說的最後一行拋出異常,即

PrivateKey privKey = kf.generatePrivate(keySpec);

以上行用於keyspecs被設置正確,即

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

所以實際的問題是與編碼的字節陣列。你在byte [] encoded = Base64.decode(privKeyPEM);之後完成了System.out,看看輸出是什麼。

我知道如果郵件是MIME格式,那麼在某些字符後面會附加回車符和換行符的組合,這樣字符串對於電子郵件系統或任何您使用它的地方都不會太長。

最後一個字符串測試在您使用原文的一些「\ 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,看看編碼的字節數組是什麼樣子,並在此之前檢查字符串privKeyPEM,看看是否有任何額外的字符不在其中。

希望這hepls。

+1

我上傳了'encoded'的輸出。 http://pastebin.com/YUsNdhgW。我也將測試更改爲純字符串,沒有'\ n',它也不起作用。 – Niklas

+0

我也上傳了一個輸出爲字符串的截圖。 – Niklas

+0

Base64解碼忽略換行符,通常是全部空格。 –

相關問題