2012-07-19 51 views
-1

我已經創建了與我的服務器的ssl套接字連接。服務器向我發送RC4密鑰,並使用密鑰創建密碼並將其綁定到現有套接字的輸入和輸出流。我正在於試圖從輸入流中讀取以下錯誤:使用密碼時SSL庫失敗

javax.net.ssl.SSLProtocolException:讀取錯誤:SSL = 0x32fbf8:失敗的SSL庫,通常一個協議錯誤

是否有可能解密工作不正常或RC4密鑰密碼不正確。這種錯誤的原因是什麼?我在android 2.3.3上的應用程序中執行此操作。

多一個查詢,android 2.3.3支持sslv23(openssl)。如果是的話怎麼可以實例化相同的?(在Windows客戶端,我設置會話上下文與rc4鍵,它的工作完全好)

我是新來的java和android和來自VC + +背景。 專家和程序員請給我啓發我的疑問。我的代碼如下:

sslContext = SSLContext.getInstance("TLS"); 
/* some code to initialize ssl context */ 
SSLSocketFactory sslSocketfactory = sslContext.getSocketFactory(); 
sock = (SSLSocket) sslSocketfactory.createSocket(host,port1); 
sock.setSoTimeout(12000); 

is = new DataInputStream(new BufferedInputStream(sock.getInputStream(), 
           16384)); 
os = sock.getOutputStream(); 
/* some more code using above mentioned is and os to recieve rc4 key and 
    write it into a byte array */ 

SecretKey key2 = new SecretKeySpec(reverserRc4InBytes, 0, reverserRc4InBytes.length, "RC4"); 
Cipher cipherOS = Cipher.getInstance("RC4"); 
cipherOS.init(Cipher.ENCRYPT_MODE, key2); 


Cipher cipherIS = Cipher.getInstance("RC4"); 
cipherIS.init(Cipher.DECRYPT_MODE, key2); 
cos = new CipherOutputStream(os,cipherOS); 
cis = new CipherInputStream(is,cipherIS); 
+0

爲什麼服務器,如果您已經使用SSL/TLS發送給您的RC4密鑰? – Bruno 2012-07-19 09:57:38

+0

我正在嘗試按照我爲Windows客戶端所做的相同方式執行此操作。協議爲:1.創建客戶端套接字並建立連接,接收rc4密鑰並使用rc4密鑰來解密進一步的通信。所以我決定用接收到的密鑰創建一個密碼並綁定使用密碼輸入流。我錯了嗎? – grv 2012-07-19 10:02:40

+1

爲什麼要通過SSL/TLS進行兩次加密,並且使用您自己的額外密鑰(無論您是在Windows,Java還是任何其他語言/平臺),您似乎都會通過SSL/TLS通道清楚地傳遞該密鑰?如果你只在現有客戶端上進行一次加密(沒有底層SSL/TLS),那麼通過在通信開始時直接傳遞密鑰更加糟糕。 – Bruno 2012-07-19 10:05:26

回答

1

據我所知,你第一次做的SSL/TLS連接以某種方式交換RC4密鑰,然後你使用它來加密和解密的結果,而不是讓SSL/TLS堆棧爲您完成這一切。 (這顯然是不必要的迂迴,而目前還不清楚如何安全的,這是因爲SSL/TLS爲您提供比加密的更多,尤其是與完整性。)

The server is implemented in C and using an existing SSL stack .. sslv23 to be specific.

SSLv23是不是一個真正的「堆棧」(由「stack」我的意思是一個實現:JSSE,OpenSSL,.Net的安全API,...)。 SSLv23通常指的是SSLv3,其中the initial Client Hello message is wrapped in SSLv2 format。對於同時支持SSLv3和SSLv3/TLSv1.x的客戶端,此包裝發生在客戶端。服務器支持應該修復哪些版本,尤其是,如果您的服務器支持SSLv3及更高版本,則不需要使用該技巧。 (請注意,JSSE支持V2包客戶端Hello格式,但實際上並不支持的SSLv2。我想這也是爲Android的情況。)

javax.net.ssl.SSLProtocolException: Read error: ssl=0x32fbf8: Failure in SSL library, usually a protocol error

這表明,一些不兼容的服務器之間發生客戶端。這可能有幾個原因:

  • 您的服務器只支持SSLv2(而不是3)。假設您的服務器至少支持SSLv3(例如,您可以使用Wireshark檢查握手是否完成)。
  • 服務器上的SSL/TLS實現存在更常見的問題。 (您可以嘗試使用其他工具(如openssl s_client)連接到它,至少要查看是否可以建立連接。)
  • 您的密鑰交換協議希望SSL/TLS連接在此處結束,而將手冊之後在普通的TCP套接字上處理連接。只有在使用SSL/TLS的部分期間,您可能必須將Socket用作SSLSocket,然後再恢復爲普通Socket。 ()

    您可以嘗試使用createSocket (Socket s, String host, int port, boolean autoClose)autoClose=false將服務器升級到SSLSocket,並從普通套接字獲取I/O以執行手動加密。

    我認爲這應該會導致SSLSocket方的其他問題,特別是當服務器關閉它的SSL/TLS連接時,儘管如此。這只是一個猜測,這種方法可能會起作用。

無論如何,我不認爲你看到有什麼與你使用手動CipherSSLSocket的I/O流的問題,因爲異常發生在底層,這應該只要您在此處讀取/寫入的數據被隱藏。

+0

我很抱歉,我的回覆嘗試最終編輯了你的帖子。我怎樣才能恢復它。 – grv 2012-07-20 05:14:31

+0

>>根據我的理解,您首先製作SSL/TLS連接>>以交換RC4密鑰>然後用它來加密和解密結果,而不是讓SSL/TLS >>堆棧爲你做的一切。 你是對的。 – grv 2012-07-20 05:18:02

+0

非常感謝您的建議。它們有很大的幫助。我們已經有了一個與服務器交互的現有windows客戶端1.創建SSL連接2.接收rc4(openssl)鍵3.設置會話上下文的關鍵字(使用開放ssl函數EVP_CIPHER_CTX_init,EVP_CipherInit_ex) 4。與服務器通信(服務器是RFB)我應該如何嘗試將rc4密鑰設置爲已經存在的ssl套接字連接? – grv 2012-07-20 05:18:12

0

我不認爲你已經正確理解你的任務。 要麼你應該使用SSL 你需要實現這種本土密碼。

否則你應該找一個理智的工作;-)

相關問題