2012-07-19 86 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 你需要实现这种本土密码。

否则你应该找一个理智的工作;-)