Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

Flash Advent Calendar 15日目 - WebSocketのメッセージの暗号化 -

昨日の記事で送付するヘッダーは作れたので、今日はメッセージの暗号化を書こうと思います。
WebSocketのハンドシェイクをエミュレートする

昨日も書きました、これらの処理はブラウザがやってくれるので
本来は自前でやる必要のない機能なので、笑い話としてみてもらえればと思います。

参考サイト

クライアントからサーバーに向かうメッセージはXOR暗号化(32ビットキー)を使用してマスクされます。

フォーマット

Frame format:
​​
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

え。。。

これやらないと、メッセージを送れないの??

まじか・・・

やるか・・・

/**
 * @param  {string} value
 * @return {array}
 * @public
 */
stringToArray = function (value)
{
    const array  = [];
    const length = value.length;
    for (let idx = 0; idx < length; ++idx) {

        const code = value.charCodeAt(idx);
        if (code > 127) {

            const values = encodeURIComponent(value[idx]).split("%");
            const length = values.length;
            for (let idx = 1; idx < length; ++idx) {
                array[array.length] = parseInt(values[idx], 16);
            }

            continue;
        }

        array.push(code);
    }

    return array;
};

/**
 * @param {Event} event
 * @return {void}
 * @public 
 */
function (event)
{
    // ByteArrayクラスも自前する必要があるのですが、ここはまたいつか・・・
    const byteArray = new ByteArray();

    byteArray.writeByte(129); // fixed opcode 1 only

    // 受け取ったメッセージを数値に変換
    const values = stringToArray(event.data);

    let length = values.length;
    if (126 > length) {

        // メッセージが126桁以下ならペイロードの長さをセット
        byteArray.writeByte(length);

    } else if (length > 125 && length < 65536) {

        // 126以上なら固定値で126をセットして、次にペイロードの長さをセット
        byteArray.writeByte(126);
        byteArray.writeShort(length);

    } else {

        // 65536以上なら固定値で127をセットして、判定の0を入れてペイロードの長さをセット
        byteArray.writeByte(127);
        byteArray.writeUnsignedInt(0);
        byteArray.writeUnsignedInt(length);

    }

    // 最後に文字列を数値化したデータをセット 
    byteArray.length += length;
    byteArray.set(values, byteArray.position);

ヘッダーと一緒に送信して完了です。

メッセージを送るだけでも一苦労です。。。

これを、ブラウザは自動でやってくれるので本当に感謝です。。。

明日は何を書こうかな・・・

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?