本文介绍了使用SSLEngine在NIO SSL握手过程中抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在NIO SSL握手时遇到以下异常。在握手过程中,

I am getting following exception on NIO SSL handshake. During handshake process,

在客户端,

a)NEED_WRAP

a) NEED_WRAP

b)NEED_UNWRAP

b) NEED_UNWRAP

c)NEED_TASK

c) NEED_TASK

d)NEED_UNWRAP - 获得以下异常调用unwrap。

d) NEED_UNWRAP - getting the following exception on calling unwrap.

javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 1
    at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1371)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:790)
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
    at com.ipay.ssl.SSlClientNio.doHandshake(SSlClientNio.java:65)
    at com.ipay.ssl.SSlClientNio.main(SSlClientNio.java:220)
javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 1
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:133)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
        at sun.security.ssl.Handshaker$1.run(Handshaker.java:808)
        at sun.security.ssl.Handshaker$1.run(Handshaker.java:806)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1299)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

请告诉我,我所关注的握手顺序是否正确。我完全停留在握手部分。

Please tell me if handshake sequence i am following is correct. I am completely stuck on handshaking part.

//编辑

以下是握​​手代码。

void doHandshake(SelectionKey key, SSLEngine engine,
            ByteBuffer myNetData, ByteBuffer peerNetData) throws Exception {

        SocketChannel socketChannel = (SocketChannel)key.channel();
        // Create byte buffers to use for holding application data
        int appBufferSize = engine.getSession().getApplicationBufferSize();
        ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);

        // Begin handshake
        engine.beginHandshake();
        SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
        System.out.println("handshake"+hs);

        // Process handshaking message
        while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
            hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
             switch (hs) {
                case NEED_UNWRAP:
                System.out.println("Reached NEED UNWRAP");
                // Receive handshaking data from peer
                if (socketChannel.read(myNetData) < 0) {
                    // Handle closed channel
                    System.out.println("not able toRead data from channel to buffer at client");
                }
                myNetData.flip();
                // Process incoming handshaking data
                if(myNetData.limit() == 0)
                {
                    myNetData.clear();
                    break;
                }
                myAppData.clear();
                System.out.println("checking limit"+myNetData.limit());
                SSLEngineResult res = engine.unwrap(myNetData, myAppData);
                myNetData.compact();
                // Getting handshake status
                hs = res.getHandshakeStatus();
                System.out.println("Debugging in NEED_UNWRAP-->"+hs);
                // Check status
                switch (res.getStatus()) {
                case OK :
                    // Handle OK status
                    System.out.println("OK");
                    break;
                case BUFFER_OVERFLOW:
                    System.out.println("BUFFER OVERFLOW");
                    break;
                case BUFFER_UNDERFLOW:
                    System.out.println("BUFFER UNDERFLOW");
                    break;
                case CLOSED:
                    System.out.println("CLOSED");
                    break;

                // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED
               // ...
                }
                break;
            case NEED_WRAP :
                System.out.println("Reached NEED WRAP");
                // Empty the local network packet buffer.
                myNetData.clear();
                // Generate handshaking data
                res = engine.wrap(myAppData, myNetData);
                // Getting handshake status
                hs = res.getHandshakeStatus();
                System.out.println("Debugging in NEED_WRAP-->"+hs);
                System.out.println(engine.getSession().getApplicationBufferSize());
                System.out.println(myNetData.capacity());
                // Check status
                switch (res.getStatus()) {
                case OK :
                    System.out.println("OK");
                    myNetData.flip();

                    // Send the handshaking data to peer
                    while (myNetData.hasRemaining()) {
                        if (socketChannel.write(myNetData) < 0) {
                            // closing socket channel
                        }
                    }
                    break;
                case BUFFER_OVERFLOW:
                    System.out.println("BUFFER OVERFLOW");
                    break;
                case BUFFER_UNDERFLOW:
                    System.out.println("BUFFER UNDERFLOW");
                    break;
                case CLOSED:
                    System.out.println("CLOSED");
                    break;
                // Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED
               // ...
                }
                    break;
            case NEED_TASK :
                System.out.println("NEED TASK");
                System.out.println("Debugging in NEED_TASK-->"+hs);
                Runnable task;

                while((task=engine.getDelegatedTask()) != null)
                {
                System.out.println("Inside while loop");
                ExecutorService executorService = Executors.newFixedThreadPool(1);
                executorService.execute(task);

                // Handle blocking tasks
                }
                // Whether following code is required
                hs=engine.getHandshakeStatus();
                System.out.println("Printing"+engine.getHandshakeStatus());
                break;
            case FINISHED:
                System.out.println("Debugging in FINISHED-->"+hs);
                System.out.println("handshake done");
                break;

            //...
            }
        }

        // Processes after handshaking
        //...
    }

//更新EXCEPTION ...

//UPDATED EXCEPTION...

我在服务器端遇到异常。
我用谷歌搜索它。但是不知道。

I am getting following exception on server side.I googled it.But getting no idea.

请帮我这一部分..

javax.net.ssl.SSLProtocolException: Handshake message sequence violation, state = 1, type=1
javax.net.ssl.SSLProtocolException: Handshake message sequence violation, state = 1, type = 1

    at sun.security.ssl.Handshaker.checkThrown(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(Unknown Source)
    at sun.security.ssl.SSLEngineImpl.unwrap(Unknown Source)
    at javax.net.ssl.SSLEngine.unwrap(Unknown Source)
    at com.ipay.ssl.SSLServerNio.doHandshake(SSLServerNio.java:55)
    at com.ipay.ssl.SSLServerNio.main(SSLServerNio.java:216)
Caused by: javax.net.ssl.SSLProtocolException: Handshake message sequence violation, state = 1, type = 1
    at sun.security.ssl.ServerHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker$1.run(Unknown Source)
    at sun.security.ssl.Handshaker$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.ssl.Handshaker$DelegatedTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

varghese

推荐答案

你不应该'跟随''序列' '使用 SSLEngine 时。您应该对其提供的状态和例外做出反应

You're not supposed to 'follow' a 'sequence' when using the SSLEngine. You are supposed to react to the states and exceptions it provides:


  • NEED_WRAP :从应用程序发送缓冲区到网络发送缓冲区执行 wrap()

  • NEED_UNWRAP :从网络接收缓冲区到应用程序接收缓冲区执行 unwrap()

  • BUFFER_OVERFLOW :在网络发送缓冲区上执行 flip()/ write()/ compact(),或者应用程序接收缓冲区中的flip()/ get()/ compact()

  • BUFFER_UNDERFLOW :在网络接收缓冲区上执行 read(),或者在应用程序发送缓冲区中没有任何内容。

  • NEED_WRAP: do a wrap() from the application send buffer to the network send buffer
  • NEED_UNWRAP: do an unwrap() from the network receive buffer to the application receive buffer
  • BUFFER_OVERFLOW: do a flip()/write()/compact() on the network send buffer, or a flip()/get()/compact() on the application receive buffer
  • BUFFER_UNDERFLOW: do a read() on the network receive buffer, or there is nothing in the application send buffer.

编辑这是什么?

if(myNetData.limit() == 0)
{
    myNetData.clear();
}

这个?

case NEED_WRAP:
    myNetData.clear();

你不能只丢掉引擎数据。完全摆脱这些。除了 flip(),compact(),wrap(), unwrap()之外,你无法对网络发送或接收缓冲区做任何事情。 此外,您似乎没有单独的网络发送和接收缓冲区。你需要两者。您需要四个:net send,net receive,application send和application receive。网络缓冲区需要具有 SSLEngine建议的大小。

You can't just throw away engine data. Get rid of these altogether. You can't do anything to the network send or receive buffers except flip(), compact(), wrap(), and unwrap(). Also it doesn't appear that you have separate net send and receive buffers. You need both. You need four altogether: net send, net receive, application send, and application receive. The network buffers need to be of the sizes advised by the SSLEngine.

除此之外,你不是完全按照我上面所说的做出反应。例如,采用 NEED_UNWRAP 路径。您应该:

Apart from that, you aren't really reacting exactly as I said above. For example, take the NEED_UNWRAP path. You should:


  1. unwrap()从net recv缓冲区到应用程序接收缓冲。

  2. 如果您然后获取 BUFFER_UNDERFLOW read()进入净接收缓冲区并重复(1)。

  1. unwrap() from the net recv buffer to the application receive buffer.
  2. If you then get BUFFER_UNDERFLOW, read() into the net receive buffer and repeat (1).

对于 NEED_WRAP


  1. wrap()来自应用程序发送缓冲区到网络发送缓冲区。

  2. 如果你得到 BUFFER_OVERFLOW write()并重复3.

  1. wrap() from the application send buffer to the network send buffer.
  2. If you then get BUFFER_OVERFLOW, write() from the net send buffer and repeat 3.

当您需要读取应用程序数据时:

When you need to read application data:


  1. 来自应用程序的flip()/ get()/ compact()缓冲。

  2. 如果这导致 BufferUnderflowException unwrap()并且重复,记住 unwrap()可能导致 NEED_WRAP NEED_WRAP BUFFER_UNDERFLOW BUFFER_ OVERFLOW。

  1. flip()/get()/compact() from the application receive buffer.
  2. If that results in a BufferUnderflowException, unwrap() and repeat, bearing in mind that the unwrap() may cause NEED_WRAP or NEED_WRAP or BUFFER_UNDERFLOW or BUFFER_OVERFLOW.

当您需要编写申请数据时:

When you need to write application data:


  1. 将put()放入应用程序发送缓冲区。

  2. 如果这导致 BufferOverflowException flip()/ wrap()/ compact(),请记住 wrap()可能导致 NEED_WRAP NEED_WRAP BUFFER_UNDERFLOW BUFFER_OVERFLOW

  1. put() into the application send buffer.
  2. If that results in a BufferOverflowException, flip()/wrap()/compact(), bearing in mind that the wrap() may cause NEED_WRAP or NEED_WRAP or BUFFER_UNDERFLOW or BUFFER_OVERFLOW.

这篇关于使用SSLEngine在NIO SSL握手过程中抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 00:05