这已经让我发疯了几天。我使用SSL引擎使用java nio和ssl加密创建了一个客户端。握手可以正常工作,我向网站写入GET请求,并且工作正常(我获得了包含200个代码的标头)。问题是,当网站将数据包发回时,在第二个数据包上,我收到BadPaddingException。这是我的读取方法:
public void read(SelectionKey key,ByteBuffer readBuffer) throws IOException, BadPaddingException { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer clientSSLData = ByteBuffer.allocate(getPacketBufferSize()); System.out.println("Reading data. PacketBufferSize: "+(getPacketBufferSize())); int length = socketChannel.read(clientSSLData); System.out.println("read "+length+" bytes"); if (length == -1){ System.out.println("Length is -1 which means nothing was read from the channel "); socketChannel.close(); return; } clientSSLData.flip(); readBuffer.clear(); SSLEngineResult res = sslEngine.unwrap(clientSSLData, readBuffer); System.out.println(res.toString()); }
我的获取请求很简单,例如:“获取\ r \ n主机:www.google.com \ r \ n \ r \ n”
基本上,如果它是一个像https://www.example.com这样的小型网站,那么我接收它不会有任何问题,因为它是按一次阅读发送的。但是,如果我执行https://www.google.com之类的操作,则会收到BadPaddingException。有任何想法吗?谢谢!
编辑:异常是…
javax.net.ssl.SSLException:sun.security.ssl.SSLEngineImpl.readRecord(在sun.security.ssl.Alerts.getSSLException(未知源)处的MAC记录错误。 sun.security.ssl.SSLEngineImpl.readNetRecord上的“未知源”(sun.security.ssl.SSLEngineImpl.unwrap处的未知源)(javax.net.ssl.SSLEngine.unwrap中的Unknown Source)(ssl.engine处的Unknown Source)。位于java.lang的ssl.engine.impl.ChannelHandler.run(ChannelHandler.java:69)的ssl.engine.impl.ChannelHandler的impl.SecureIO.read(SecureIO.java:244) .Thread.run(未知源)原因:javax.crypto.BadPaddingException:sun.security.ssl.EngineInputRecord.decrypt处的记录不良MAC(未知源)… 8更多
您做错了。当您需要获取数据时,您应该:
unwrap().
同样,当您需要放置数据时,您应该:
wrap().
或者在需要冲洗时执行所有操作。
您的主要接口应该与引擎一起使用,并且仅与通道有关,因为引擎告诉您有关缓冲区下溢和上溢的信息。
同样,您必须让引擎决定握手(NEED_WRAP / NEED_UNWRAP),而不是尝试决定握手。
这SSLEngine是一件非常困难的事情。许多人尝试过:很少成功。要获得成功的成功,那就是商业产品的基础,请在此处参阅SSLEngineManager我的书《 Java基础网络》 (Springer 2006)源代码中的类。
SSLEngine
SSLEngineManager