3

Java で WebSocket フレーム デコーダを作成しました。

private byte[] decodeFrame(byte[] _rawIn) {
        int maskIndex = 2;
        byte[] maskBytes = new byte[4];

        if ((_rawIn[1] & (byte) 127) == 126) {
            maskIndex = 4;
        } else if ((_rawIn[1] & (byte) 127) == 127) {
            maskIndex = 10;
        }

        System.arraycopy(_rawIn, maskIndex, maskBytes, 0, 4);

        byte[] message = new byte[_rawIn.length - maskIndex - 4];

        for (int i = maskIndex + 4; i < _rawIn.length; i++) {
            message[i - maskIndex - 4] = (byte) (_rawIn[i] ^ maskBytes[(i - maskIndex - 4) % 4]);
        }

        return message;
    }

動作しますが、有効なフレームのみをデコードするためにフレームを検証する方法がわかりません。

残念ながら、プロトコルの説明http://tools.ietf.org/html/rfc6455では、フレームの検証についてはあまり説明されていません。

4

4 に答える 4

0

Websocket プロトコルには、探しているものであれば、いかなる種類のチェックサムも含まれていません。データ フレームにエラーがある場合、唯一の方法は、データが間違っているか、後続のフレームが「おかしい」(予期しないオペコード、予想より長いまたは短いなど) であるためです。

于 2013-08-21T21:47:27.260 に答える
0

設計されていない Websocket サーバーに接続するアプリケーションに対する最初のセーフガードは、HTTP Websocket ハンドシェイクです。が含まれていない場合Upgrade: websocketSec-WebSocket-KeyまたはSec-WebSocket-Version: 13RFC6455 Websocket クライアントでさえなく、拒否する必要がある場合。

2 番目のセーフガードは、WebSocket を使用しているが、別のアプリケーション用に設計されたクライアントに対して機能します。これがSec-WebSocket-Protocol: somethingヘッダーです。このヘッダーはオプションですが、クライアントが使用するアプリケーションを識別する文字列にする必要があります。値がサーバーが期待するアプリケーションと一致しない場合、クライアントは拒否されます。

Websocket を使用して適切なサーバーに接続していると思い込んでいるが、実際には Websocket プロトコルの実装にバグがあるクライアントに対する最後の防御策は、予約ビットです。

マスキング キーまたは長さに不正な値はありません。長さが間違っていると、データが不十分または多すぎるとペイロードとして解釈された後に次のフレームが開始されますが、これを検出するのは難しい場合があります。これが発生した唯一の兆候は、主張されたフレームの最初のバイトが意味をなさない場合です。

フレームの 2 番目、3 番目、4 番目のビットは予約されており、RFC によれば、「拡張機能がネゴシエートされない限り、0 でなければなりません [...] ゼロ以外の値が受信された場合 [...] 受信エンドポイントは WebSocket に失敗しなければなりません」接続。」。これらのビットを使用するエクステンションはまだありません。したがって、これらのビットのいずれかがゼロ以外の場合、何かが間違っています。

必要に応じて、すべてのメッセージが開始および/または終了する特定の魔法のバイト値のように、プロトコルレベルでさらに安全策を追加できます (マルチフラグメントメッセージがあり、ブラウザがこれを使用できることに注意してください)する感じです)。{私が現在開発しているアプリケーションは JSON ペイロードを使用しているため、メッセージが で始まり で終わる有効な JSON 文字列でない場合}、クライアントが壊れていることがわかります (または、サーバーのフレームのデコード方法が壊れている可能性がはるかに高いです)。

于 2013-08-21T22:06:29.283 に答える
-1

私は websocket にまったく慣れていませんが、websocket への現在の関心により、これを支援できる可能性があります。

https://www.rfc-editor.org/rfc/rfc6455#section-5.2 は、データ フレームの概要を示しています。最初のバイトの最後の 4 つをテストするので、raw_in[0]<<<4. これにより、最後の 4 ビットが得られます。私はまだビット操作が得意ではないので、最後の 4 ビットを取得して 0000 1111-0000 0000 と 1111 0000-0000 0000 を表す方法がわかりません。ご覧のとおり、0001 op コードはテキスト フレーム、0010 op コードはバイナリ フレームなどです。したがって、テキスト フレームのみを除外する場合は、最初のバイトの最後の 4 ビットが 0001 であることをテストするだけです。

于 2013-08-21T21:52:12.733 に答える