使用密码时SSL库失败

时间:2012-07-19 09:38:29

标签: java android sockets encryption ssl

我已经与我的服务器创建了一个ssl套接字连接。服务器向我发送RC4密钥,然后使用密钥创建密码并将其绑定到现有套接字的输入和输出流。尝试从输入流中读取时出现以下错误:

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);

2 个答案:

答案 0 :(得分:1)

根据我的理解,您首先建立SSL / TLS连接以某种方式交换RC4密钥,然后您使用它来加密和解密结果,而不是让SSL / TLS堆栈完成所有操作为了你。 (这显然是不必要的复杂,并且不清楚这是多么安全,因为SSL / TLS为您提供的不仅仅是加密,尤其是完整性。)

  

服务器在C中实现并使用现有的SSL堆栈。   sslv23具体。

SSLv23实际上不是“堆栈”(“堆栈”我的意思是实现:JSSE,OpenSSL,.Net的安全API,......)。 SSLv23通常指的是the initial Client Hello message is wrapped in SSLv2 format中的SSLv3。对于同时支持SSLv3和SSLv3 / TLSv1.x的客户端,此包装发生在客户端。应该修复服务器支持的版本,特别是,如果您的服务器支持SSLv3及更高版本,则不需要使用该技巧。 (请注意,JSSE支持v2包装的Client Hello格式,但实际上并不支持SSLv2。我想Android也是如此。)

  

javax.net.ssl.SSLProtocolException:读取错误:ssl = 0x32fbf8:失败   在SSL库中,通常是协议错误

这表示您的服务器和客户端之间发生了不兼容的事情。可能有几个原因:

  • 您的服务器仅支持SSLv2(不是3)。假设您的服务器至少支持SSLv3(例如,您可以使用Wireshark检查握手是否完成。)
  • 服务器上的SSL / TLS实现存在更普遍的问题。 (您可以尝试使用其他工具(例如openssl s_client)连接到它,至少可以查看是否可以建立连接。)
  • 您的密钥交换协议期望SSL / TLS连接在那里结束,然后在普通TCP套接字上手动处理连接。您可能必须仅在使用SSL / TLS的部分中将Socket用作SSLSocket,然后再恢复为普通Socket。 ()

    您可以尝试为服务器建立一个普通套接字,使用带有SSLSocket的{​​{3}}将其升级为autoClose=false,并从普通套接字获取I / O以执行您的手册加密。

    我认为这应该会导致SSLSocket方面出现其他问题,尤其是当服务器关闭SSL / TLS连接时。这只是一个猜测,这种方法可能有用。

无论如何,我认为您所看到的问题与您在Cipher的I / O流中手动使用SSLSocket无关,因为异常发生在底层对于您所读取/写入的数据而言应该隐藏的层。

答案 1 :(得分:0)

我认为你没有正确理解你的作业。 要么你应该使用SSL ,你需要实现这个本土密码。

否则你应该找一份更健全的工作; - )