2010-11-11 315 views
1

我試圖發送一個客戶端證書到服務器。我正在HttpURLConnection上構造一個SSLSocketFactory。java HttpsURLConnection和發送客戶端證書

我想我需要通過KeyManager提供SSLSocketFactory知道的密鑰。我遇到的麻煩是將Key輸入到KeyManager中。

私鑰和證書位於PEM文件中(並且它們不能位於密鑰庫文件中)。我知道如何讀取/解碼文件,並且我已經成功驗證了客戶端證書。但是,當我試圖把重點(以字節[])進入的KeyManager,它抱怨:java.security.KeyStoreException: key is not encoded as EncryptedPrivateKeyInfo

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
KeyStore ks = KeyStore.getInstance("JKS"); 
ks.load(null); // init the keystore 

// This Fails: it wants it encoded as EncryptedPrivateKeyInfo 
ks.setKeyEntry("MyAlias", clientKeyAsBytes, new Certificate[]{clientCert}); 

什麼是做到這一點的正確方法?

+0

只是讓我更好地理解根你的問題,你在做什麼背景?有許多庫和框架可以自動處理這類事情。一個這樣的庫是JSch(J Secure Channel)庫。 – 2010-11-12 00:11:58

+0

這是客戶不想使用任何額外的庫(這將不得不審查)的代碼。客戶正在調用一個需要授權客戶端證書的Web服務。部署使用.PEM文件。 – 2010-11-12 03:01:05

回答

2

使這項工作的訣竅是將PEM文件轉換爲不同的格式。我這樣做是外部現在使用OpenSSL

openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out client-key.der -outform DER 
openssl x509 -in cert.pem -inform PEM -out client-cert.der -outform DER 

然後,我是能夠成功地將密鑰和證書添加到內存中的密鑰庫:

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(clientKeyAsBytes); 
PrivateKey ff = kf.generatePrivate(keysp); 

// This works with DER format of key bytes 
ks.setKeyEntry("MyAlias", clientKeyAsBytes, new Certificate[]{clientCert}); 
1

我得到了同樣的異常用於讀取私人密鑰來自RSA加密文件。我用的,而不是建立在它的密鑰庫中的項解決了該問題的二進制格式:

keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey.getEncoded(), new X509Certificate[]{(X509Certificate)cert}); 

我簡單地創建爲重點對象,而不是:

keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey, password.toCharArray(), new X509Certificate[]{(X509Certificate)cert});