-1

我已经与我的服务器创建了一个 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);
4

2 回答 2

1

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

该服务器是用 C 语言实现的,并使用现有的 SSL 堆栈 .. sslv23 来具体说明。

SSLv23 并不是真正的“堆栈”(“堆栈”是指实现:JSSE、OpenSSL、.Net 的安全 API,...)。SSLv23 通常是指 SSLv3,其中初始客户端 Hello 消息以 SSLv2 格式包装。对于同时支持 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 的部分中仅使用您的Socketas an SSLSocket,然后再恢复为纯Socket文本。()

    您可以尝试为您的服务器建立一个普通套接字,将其升级为SSLSocket使用createSocket (Socket s, String host, int port, boolean autoClose)withautoClose=false并从普通套接字获取 I/O 以进行手动加密。

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

无论如何,我认为您看到的问题与您Cipher从 的 I/O 流中手动使用没有任何关系SSLSocket,因为异常发生在底层,就您读取的数据而言,它应该被隐藏/写有担心。

于 2012-07-19T17:48:59.717 回答
0

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

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

于 2012-07-20T00:50:07.373 回答