Java SSL握手失败

Java SSL握手失败,java,ssl,https,jsse,sslengine,Java,Ssl,Https,Jsse,Sslengine,我在学习SSL通信时遇到了这个问题。我正在编写一个简单的客户端,它试图与本地apache服务器握手。服务器已启用https。我将服务器证书添加到所有可能的信任存储中(jdk中的一个&程序也使用的一个)。但握手状态永远不会结束。持续处于需要任务状态 在第一次进入循环时,我得到一个sun.security.ssl.Handshaker$DelegatedTask。此后,状态为“需要_任务”,任务为空。 . 我对以下代码的理解错误\缺陷在哪里 注意:我从以下教程中获取了代码: 卡在NEED_任务状态

我在学习SSL通信时遇到了这个问题。我正在编写一个简单的客户端,它试图与本地apache服务器握手。服务器已启用https。我将服务器证书添加到所有可能的信任存储中(jdk中的一个&程序也使用的一个)。但握手状态永远不会结束。持续处于需要任务状态 在第一次进入循环时,我得到一个sun.security.ssl.Handshaker$DelegatedTask。此后,状态为“需要_任务”,任务为空。 . 我对以下代码的理解错误\缺陷在哪里

注意:我从以下教程中获取了代码:

卡在NEED_任务状态的握手代码如下:

void doHandshake(SocketChannel socketChannel, SSLEngine engine,
            ByteBuffer myNetData, ByteBuffer peerNetData) throws Exception {

        // Create byte buffers to use for holding application data
        int appBufferSize = engine.getSession().getApplicationBufferSize();
        ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);
        ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);
        // Begin handshake
        engine.beginHandshake();
        SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
        int i=0;
        // Process handshaking message
        while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
            hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
            i++;
            switch (hs) {

            case NEED_UNWRAP:
                // Receive handshaking data from peer
                if (socketChannel.read(peerNetData) < 0) {
                    // The channel has reached end-of-stream
                }

                // Process incoming handshaking data
                peerNetData.flip();
                SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
                peerNetData.compact();
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                case OK :
                    // Handle OK status
                    break;

                // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED

                }
                break;

            case NEED_WRAP :
                // Empty the local network packet buffer.
                myNetData.clear();

                // Generate handshaking data
                res = engine.wrap(myAppData, myNetData);
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                case OK :
                    myNetData.flip();

                    // Send the handshaking data to peer
                    while (myNetData.hasRemaining()) {
                        socketChannel.write(myNetData);
                    }
                    break;

                // Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED

                }
                break;

            case NEED_TASK :
                Runnable task =engine.getDelegatedTask();
                if(task!= null) {
                    //task.run();
                    new Thread(task).start();
                }// Handle blocking tasks

                break;

            // Handle other status:  // FINISHED or NOT_HANDSHAKING

            }
        }
        // Processes after handshaking

    }
无效握手(SocketChannel SocketChannel、SSLEngine引擎、,
ByteBuffer myNetData、ByteBuffer peerNetData)引发异常{
//创建用于保存应用程序数据的字节缓冲区
int-appBufferSize=engine.getSession().getApplicationBufferSize();
ByteBuffer myAppData=ByteBuffer.allocate(appBufferSize);
ByteBuffer peerAppData=ByteBuffer.allocate(appBufferSize);
//开始握手
引擎。开始震动();
SSLEngineResult.HandshakeStatus hs=engine.getHandshakeStatus();
int i=0;
//处理握手消息
而(hs!=SSLEngineResult.HandshakeStatus.FINISHED&&
hs!=SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING){
i++;
开关(hs){
案例需要展开:
//从对等方接收握手数据
if(socketChannel.read(peerNetData)<0){
//这条水道已到了河的尽头
}
//处理传入的握手数据
peerNetData.flip();
SSLEngineResult res=引擎展开(peerNetData,peerAppData);
peerNetData.compact();
hs=res.getHandshakeStatus();
//检查状态
开关(res.getStatus()){
案例OK:
//处理正常状态
打破
//处理其他状态:缓冲区下溢、缓冲区溢出、关闭
}
打破
案例需要包装:
//清空本地网络数据包缓冲区。
myNetData.clear();
//生成握手数据
res=engine.wrap(myAppData,myNetData);
hs=res.getHandshakeStatus();
//检查状态
开关(res.getStatus()){
案例OK:
myNetData.flip();
//将握手数据发送给对等方
while(myNetData.haslaining()){
socketChannel.write(myNetData);
}
打破
//处理其他状态:缓冲区溢出、缓冲区下溢、关闭
}
打破
案例需求任务:
Runnable task=engine.getDelegatedTask();
如果(任务!=null){
//task.run();
新线程(任务).start();
}//处理阻塞任务
打破
//处理其他状态://完成或未握手
}
}
//握手后的处理
}

任何帮助都将不胜感激。

问题在于我对engine.getHandShakeStatus()方法的理解不完整

我把上面的代码改为

 case NEED_TASK :
            Runnable task =engine.getDelegatedTask();
            if(task!= null) {
                //task.run();
               new Thread(task).start();
            }
            hs = engine.getHandshakeStatus();
            break;

现在它完成了握手

您需要在循环中获取握手状态,否则它在need_任务情况下永远不会改变,也许其他任务也一样。在任务完成之前,状态将保持在需要任务状态。在单独的线程中处理任务确实相当复杂。在至少让它工作之前,您最好在线运行它。通过循环写入,您也在做类似的事情。修复这两个问题需要与
选择器集成,这也是非常重要的。@EJP此任务应该做什么?此任务是否因为我没有将服务器证书添加到任何信任存储而被卡住?我只想达到握手的完成状态。这是我现在唯一的目标。这个选择器概念有教程或起始页吗?它与信任库有关,不确定是什么。你需要在循环中每次都这样做,而不仅仅是在这里。@EJP。。。对现在我明白你的意思了。我想如果你能把它作为回答,我可以把它标记为答案。