2013-01-09 69 views
1

在我們的一個應用程序中,使用BouncyCastle的PEMWriter存儲私鑰。目前我正在調查是否可以擺脫BouncyCastle依賴關係,因爲Java 7似乎擁有我們需要的所有東西。唯一的問題是我無法讀取存儲在數據庫中的私鑰作爲PEM編碼的字符串(證書/公鑰很好)。如何使用JCA讀取BouncyCastle私鑰PEM文件?

如果我保存從數據庫到文件的私有密鑰的PEM編碼字符串,我可以運行的OpenSSL的關鍵PKCS#轉換8格式是這樣的:

openssl pkcs8 -topk8 -inform PEM -outform DER \ 
       -in private_key.pem -out private_key.der -nocrypt 

輸出結果,我可以使用Base64編碼,然後閱讀使用的Java/JCA這段代碼:

byte[] privateKeyBytes = 
      DatatypeConverter.parseBase64Binary(privateKeyDERcontents); 
PrivateKey prKey = 
      KeyFactory.getInstance("RSA"). 
       generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); 

該私鑰存儲預期的公鑰匹配,也就是說我可以從明文往返密文和背部。

我的問題是:我可以直接讀取原始PEM編碼嗎?

EDIT

這裏是一個比特的碼,使用讀取所討論的字符串BouncyCastle的:

if (Security.getProvider("BC") == null) { 
    Security.addProvider(new BouncyCastleProvider()); 
} 
PEMReader pemReader = new PEMReader(new StringReader(privateKeyPEM)); 
KeyPair keyPair = (KeyPair) pemReader.readObject(); 
PrivateKey key = keyPair.getPrivate(); 

的「privateKeyPEM」是在數據庫中的PEM編碼的字符串,否則這個例子中是自成一體。有趣的是,它已經使用JCA KeyPair對象作爲輸出。爲了更改我原來的問題:我可以做同樣的代碼而不依賴於PEMReader(以及其他的BouncyCastle類)嗎?

+0

你的第一部分代碼不會與你的openssl命令一起使用。您的openssl命令會生成DER輸出,但您的java代碼base64將對其進行解碼。這是行不通的,因爲它不是以base64編碼開始的。 –

+0

@GregS:你說得對,我必須結合我實驗中的錯誤。讓我檢查一下是否有效:我會使用「-outform PEM」並剝去頁眉/頁腳(可能)或base64編碼DER輸出(不太可能)。我會盡快編輯這篇文章。 –

+0

@GregS:只需對DER編碼的base64進行編碼,那麼讓我們假設我這麼做了。如果用64個字符包裝,它與PEM一樣。 –

回答

-1

PEM文件中的密鑰已經以PKCS#8格式存儲,所以如果未使用密碼加密,您可以刪除標題(----- BEGIN RSA PRIVATE KEY -----),Base64-解碼輸入,並獲得所需的字節。

+1

我很確定這是不正確的。一個PEM文件可能包含一個PKCS#8編碼密鑰,但它可以包含其他二進制數據。一個例子是X.509證書(通常用於公鑰)以及OpenSSL的默認值是什麼(某種專有格式)。您可以將openssl轉換爲從一個轉換爲另一個,同時將PEM作爲外部編碼進行轉換 - 使用我將-inform和-outform設置爲PEM的命令。 –

+2

當然,PEM只是二進制數據的文本編碼。我正在談論這種特殊情況。在這裏,您使用Base64編碼的PKCS#8私鑰。 –

+1

轉換爲PKCS#8的openssl命令是必需的。見例如http://www.openssl.org/docs/apps/pkcs8.html - 我在文檔中似乎採用了「傳統」格式。 –

相關問題