Java SSL库在使用密码时失败

Java SSL库在使用密码时失败,java,android,sockets,encryption,ssl,Java,Android,Sockets,Encryption,Ssl,我已经创建了与服务器的ssl套接字连接。服务器向我发送RC4密钥,我使用该密钥创建密码并将其绑定到现有套接字的输入和输出流。我在尝试读取输入流时遇到以下错误: javax.net.ssl.SSLProtocolException:读取错误:ssl=0x32fbf8:ssl库中出现故障,通常是协议错误 可能是解密工作不正常或RC4密钥密码不正确。出现这种错误的原因是什么。我在安卓2.3.3上的一个应用程序中做这件事 还有一个问题,android 2.3.3是否支持sslv23(openssl)。如

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

javax.net.ssl.SSLProtocolException:读取错误:ssl=0x32fbf8:ssl库中出现故障,通常是协议错误

可能是解密工作不正常或RC4密钥密码不正确。出现这种错误的原因是什么。我在安卓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);

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

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

SSLv23并不是真正的“堆栈”(我所说的“堆栈”是指一个实现:JSSE、OpenSSL、.Net的安全API……)。SSLv23通常指SSLv3,其中。对于同时支持SSLv3和SSLv3/TLSv1.x的客户端,这种包装在客户端进行。服务器支持的版本应该是固定的,特别是,如果您的服务器支持SSLv3及以上版本,则不需要使用该技巧。(请注意,JSSE支持v2包装的客户端Hello格式,但实际上不支持SSLv2。我想Android也是如此。)

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

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

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

    您可以尝试为服务器建立普通套接字,使用with
    autoClose=false将其升级为
    SSLSocket
    ,并从普通套接字获取I/O以进行手动加密

    我认为这会在
    SSLSocket
    端造成其他问题,特别是当服务器关闭其SSL/TLS连接端时。这只是一个猜测,这种方法可能有效


无论如何,我认为您看到的问题与您从
SSLSocket
的I/O流中手动使用
密码无关,因为异常发生在底层,就你在那里读/写的数据而言,应该将其隐藏。

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


或者你应该找一份更理智的工作;-)

如果您已经在使用SSL/TLS,为什么服务器会向您发送RC4密钥?我正在尝试以与windows客户端相同的方式执行此操作。协议为:1。创建客户端套接字并建立连接,接收rc4密钥并使用rc4密钥解密进一步的通信。所以我决定用收到的密钥创建一个密码,并使用密码输入流绑定。我错了吗?为什么要加密两次,通过SSL/TLS并使用您自己的额外密钥(不管怎样,您似乎是通过SSL/TLS通道明确传递的),而不依赖于Windows、Java或任何其他语言/平台?如果在通信开始时直接传递密钥,在现有客户端上只加密一次(没有底层SSL/TLS),则情况更糟。服务器是使用现有SSL/TLS堆栈实现的,还是“自制的”使用相同的密码原理进行加密?对于Java,套接字已经由堆栈加密/解密。您是在试图通过已受保护的SSL通道加密某些内容,还是在尝试实现SSL协议的一部分?很抱歉,我试图回复的结果是编辑了您的帖子。如何将其还原。>>据我所知,您首先进行SSL/TLS连接>>以某种方式交换RC4密钥>,然后使用它>>对结果进行加密和解密,而不是让SSL/TLS>>堆栈为您完成所有工作。你完全正确。非常感谢你的建议。他们帮了大忙。我们已有一个与服务器交互的现有windows客户端1.创建SSL连接2.接收rc4(openssl)密钥3.将密钥设置为会话上下文(使用开放SSL函数EVP_CIPHER_CTX_init,EVP_CipherInit_ex)4。与服务器通信(服务器为RFB)如何尝试将rc4密钥设置为现有ssl套接字连接?@grv您无法将rc4密钥设置为现有套接字连接。SSL握手建立自己的密钥。我越来越想知道你是否真正理解了这项任务