【JS/Websocket】バイナリデータを暗号化しよう!

今回はプログラミングのお話です。

JavascriptやWebsocketが話題のメインとなります。

この記事をみるってことは知っているんだと思いますが

とりあえず、まずWebsocketについて紹介したいと思います。

Websocketって?

Web上でソケット通信を実現する技術のことですね。HTTPというのは聞いたことがあると思いますが、あれは通信規格のことなんだよね。

Websocketも通信規格のこと。

HTTPよりもリアルタイム通信に優れているので、リアルタイム通信が求められる場面で使用されています。

Websocketはバイナリデータを扱うこともできる。

そして今回はそのバイナリデータを暗号化してみよう!という記事です。

何のために暗号化するの?

バイナリデータを暗号化するっていっても、意味あるの?

確かに普通に利用するだけなら意味ないかもしれないんだけど、

Websocketを利用したゲームなどを作った際に必要になるかもしれません。

ゲームとなると必ずズルをしようとする人やボットを作る人が現れます。

ユーザーがサーバーとやりとりするデータを真似するプログラムを組めばボットが作れてしまいます。

そこで暗号化の出番!

やりとりするデータを暗号化することによって、データをみられても簡単に真似できないようにします。

ボット対策を考えている人はぜひ参考にしてください。

暗号化の方法

いろんな暗号化の仕方があると思うのですが、今回は排他的論理和を利用したバイナリデータの暗号化です。

なかなか難しそうですが、ビット演算において排他的論理和は2回行うと元に戻るやつって覚えておけばいいと思います。

めっちゃ簡単に例を挙げると

こんな感じです。

bはaとkeyの排他的論理和(xor)とった値でそれにもっかいkeyでxorとったら元に戻ったよっていう。

この方法をバイナリデータの暗号化に使用する!

2回すれば元に戻るんだから・・・つまりユーザー側から1回xor使ったデータを送ってもらってサーバーで1回xor使えば複合化されたデータになるってことですね。

ということでクライアント側にこれを設置しましょう。

Javascriptです。

引数のbufがバッファで、xorKeyが暗号化に使用するキーです。キーがばれないようにJavascriptは難読化しておきましょう。

Javascriptの難読化については検索するとツールなどがあるし、難読化の方法を紹介したページもあるので参考にしてみてください。

バイトをひとつずつとって暗号化しています。

サーバー側にもこれと同じfunctionを書いてクライアント側から受け取ったバイナリデータを渡せば複合化できます。

node.jsでバイナリデータを暗号化してみます。
testが対象のデータで、key1が暗号化に使用するキーです。
実行してみると・・・
できました!原型がないのでわかりづらいと思います。

暗号化のキーを変動させる

暗号化キーが毎回同じだとキーを特定されて同じプログラムを組まれてしまったらボットが侵入できてしまいます。

ということでキーをあるタイミングで変えるというのもアリかもしれません。

もしくは毎回変えるっていうのもアリだと思います。

キーを変える場合は、onmessageでサーバー側からクライアント側にキーを送信するといいと思います。

クライアント側のJavascriptにキーを置いておくよりかは安全です。

また、サーバーからクライアントに送るデータも暗号化するとより強力になると思います。

キーを回転させる

キーを回転させることでより読みづらい暗号化が可能です。

同じキーで暗号化すると元のパケットの先頭(パケットID)が一定の場合、

暗号化後もパケットIDが一定になってしまいます。

例をあげますと

[5, 8, 2, ……….]

[5, 6, 8, ……….]

といった同じパケットID:5のパケットは暗号化してたとしても

どちらも先頭が同じIDになってしまうので少し規則的なのがわかってしまいます。

そこでキーの回転です。

バイナリデータ毎にキーを変化させるのです。

そうすれば元が同じパケットIDのデータも暗号化後はバラバラになってほぼわからなくなります。

こちらもサーバーとクライアントに実装します。

xorBuffer関数にバイナリデータを渡した後にキーをこの関数に渡して変化させます。

ただこれは露骨なのでわかる人には一瞬で暗号化してるなってわかっちゃいます

なので、暗号化したあともとのパケットIDを先頭に追加することで一見暗号化してないようにみせるなど工夫するのもアリですね。

例えばもとのパケットIDが5で暗号化したデータが

[103, 55, 62, 5, …………]

といった感じなら

[5, 103, 55, 62, 5, ……….]

みたいなかんじで元のIDを先頭に付け足してやります。

そうすれば、暗号化してるかどうか一見わからないような気もします。

暗号化は楽しい

なにより暗号化ってけっこう楽しいです。

暗号化はほかにもいろいろ方法があるし、独自の暗号化アルゴリズムとか作ってみるのも面白いですし、Websocketでゲーム運営してるよって人やボットで困ってるって人は試してみてください!

シェアする

  • このエントリーをはてなブックマークに追加

フォローする