ダーク/ライト切り替え

【Unity X Node.js】クライアント~サーバー間でAES暗号通信してみた

投稿日2021-09-10

Picture of the logo


目次

目次を読み込み中...

Unityの暗号ライブラリCryptgraphyを使って通信してみたかったので試してみました。実用性はあまりないかと思います。普通はopensslとか使うだろうし・・・ ※この記事は2021年9月時点のものです。将来UnityまたはJavaScriptの仕様が変わり現在の手法が使えなくなる可能性がありますのでご了承のうえ参考にして下さい。

# 動作確認した環境

# クライアント側

  • ・ windows10
  • ・ Unity2020.3.17
  • ・ VS CODE

# サーバー側(ローカルホスト)

  • ・ Docker-compose
  • ・ Node.js 14.17.5

# 暗号に関する基本用語解説

用語 説明
暗号化 データの内容を他人にはわからないようにする事。
複合化 暗号化されたデータを元の状態に戻す事。
AES 現在最もポピュラーなほぼ世界標準の暗号化規格です。
encrypt 英語で暗号化のこと
decrypt 英語で複合化のこと
ハッシュ 乱数で作られた暗号化するためのための文字列。厳密には暗号とは違う。
sha256 現在割とよく用いられているハッシュの規格。今回もこれを使います。
iv initialization vectorの略。暗号を初期化するための乱数の塊のようなもの。
salt 塩じゃないよ!パスワードをハッシュ化するために使われる乱数の塊のようなもの。
key 暗号を解くための鍵である。パスワードとsaltを足したものをsha256などでハッシュ化する事で算出する。

# 今回やること

  • ・ node.jsで受信データを暗号化、複合化して返すだけの簡素なサーバーを立てる
  • ・ Unityエディターからcryptographyを使って暗号化された文字列をサーバーに送信する
  • ・ サーバーは暗号化文字列を受け取ったらcrypto-jsを使って一旦複合化する
  • ・ それをまたすぐ暗号化して元のクライアントに送信する
  • ・ Unity側でサーバーからの返信を受け取り複合化する。そしてログを表示する。

恥ずかしい

# Node.jsサーバを立ち上げる

# Node.jsの入手

OSに直にインストールする方

dockerを使う方

# Javascriptファイルを用意する

暗号化にはcrypto-jsモジュールを使います。また、クライアントとの通信にはweb-requestではなくソケット通信(net)を使います。 事前にnpm等でインストールしておいて下さい。

下記は簡単なテストプログラムです。 パスワード(Password)をかけた暗号データを受信すると、

受信データ → 複合化 → 暗号化 → クライアントに送信

ただこれだけの簡単なテストです。クライアント側は、送ったデータがそのまま送り返されてくる形にになります。厳密には複合化され再暗号化されてるので全く同一というわけではありませんが・・・


            

# 初期設定。パラメータ(定数)の設定

port:3000はウェルノウン番号といって、一般に良く使われる番号です。わかり易い半面狙われ易いので公開する場合は変えて下さい。

暗号モードはCBC、パディングはPkcs7で、わりと定番の設定です。特にこだわりが無ければこのままでいいでしょう。

passwordはその名のとおりパスワードです。全角は避け半角のみで特殊な環境依存文字も避けましょう。文字数に制限はありませんが極端に長すぎるとバグるかもしれません。

SALT_SIZEは参考にしたサイトが256にしてたのでそのまま使いました。変える場合はクライアント側と数字を揃えましょう。

# 設定が終わったらnodeサーバを起動してみる

で起動するとすぐに受信待ちになります。終了したい時はCTRL+Cで終了します。

バックグラウンド処理をしたい人はpm2を使って下さい。pm2については本題じゃないので割愛します。

# Unity側の設定

# C#スクリプトファイルをコピーする

Unityエディターのassetsフォルダーに下記の3つのファイルをコピーする Crypt.cs (暗号モジュールCryptographyの機能を簡潔にまとめたもの)

SocketNetwork.cs(ソケット通信するための機能を簡潔にまとめたもの)

CryptTest.cs (テスト用プログラム)

CryptTest.csだけ空オブジェクトにアタッチしてインスペクターの変数設定をサーバー側と合わせましょう。

# いざ実行

# 1 Unity側から送信

インスペクターのtext変数に適当な言葉を入れて、nodeサーバが起動していることを確認してunityエディターの実行ボタンを押してみましょう。

恥ずかしい言葉

繰り返しになりますが、パスワードはサーバー側のものと合わせましょう。違っていると複合化できません。

# 2 nodeサーバで受信

正しく受信されていればサーバー側の画面に下のような受信ログが表示されます。ログの前半は送信されたデータをjson形式で表示したものです。その下にjsonデータをもとに複合化されたtextが表示されています。

受信ログ

また、実際の通信はバイナリ形式で行われています。下図は実際のクライアント←→サーバ間の通信データ。あえてバイナリのまま表示してみました。サーバ側で受信後にjson形式に変換されます。クライアント側も同様です。

バイナリ形式

まずサーバ側でバイナリデータを受信してjson形式に展開ます。そしてsalt、iv、passwordを元に複合化します。今回の例では緑色のjsonデータを元に「恥ずかしい言葉」というテキストが複合化されました。

次に暗号化関数で新規にsaltとivを発行してkeyを生成して再び「恥ずかしい言葉」を暗号化します。暗号データはjson形式になり、再びバイナリデータとしてクライアント側に送信されます。

# 3 Unityクライアントで結果を受信

受信したデータは受信した時点ではバイナリ形式でサーバー側同様jsonに展開されてsalt、ivを使ってサーバー側と全く同じプロセスで複合化されます。

結果ログ






関連記事

【Unity】MagicOnionサーバを立ち上げて自己証明書でSSL通信してみる

blog

Unity向けgrpcサーバーManicOnionの導入時にSSL化やNGINXの設定に少し手こずったので備忘録も兼ねて手順をまとめておきました。

GO言語サーバーとUnityクライアント(C#)をgRPCで接続テストしてみた【入門レベル】

blog

UnityでgRPCをする場合、Magic Onionを使うのがお手軽ですが、今回はGO言語でサーバーを構築してみたかったので最低限の接続機能を自作してみました。備忘録を兼ね書き残しておきます。

【Unity】Go言語でDLLをビルドしてUnityからネイティブプラグインとして呼び出す【備忘録】

blog

Unity用ネイティブプラグインをGo言語で作成した時に手こずった部分を個人的備忘録も兼ねてまとめましたので、似たような事を考えている人はご参考までに。

UNITYで扇形を作ってみた

blog

Unity上で扇形を作る機能が標準ではついてない?ようなので自作してみました。

UNITYからMYSQLデータベースにアクセスする【初心者向け】

blog

UnityからMySQL等のデータベースにアクセスする簡単なサンプルプログラムを紹介します。若干Java Scriptの知識も必要になります。

【Unity】セーブデータの改ざんやチート対策を考えてみる

blog

ゲーム開発者にとって、チートは永遠の悩みです。どんなに対策しても開発者とチーターは「いたちごっこ」です。今回は初歩的な手段ではありますが、CRCやSHA256といった技術を使ってデータの改ざん、チート行為を検出する方法を紹介します。

UnityでTrail Rendererを使ってオブジェクトの軌跡を描画する

blog

今回はUnityでTrail Rendererを使ってオブジェクトの軌跡を描画する方法についてご紹介します。Trail Rendererを使うことで、オブジェクトがどのような軌跡を描いたかを可視化することができます。

【Unity】Json,CSVファイルを相互に変換する方法【備忘録】

blog

個人的備忘録も兼ねてUnityでインスペクタ上でテキストファイルを指定して、そのファイルから結果を取得する方法をいくつか紹介します。

FirebaseStorageからUnityへファイルを読み込み、Resourcesに保存する

blog

UnityでFIREBASEのStorageサービスから画像ファイルをダウンロードしてシーン上に表示、保存するまでの簡単な手順紹介です。

【Unity】複数のシーンがあるアプリでシーン遷移を軽くするための工夫

blog

Unityでゲームアプリを作る際にシーンをまたぐ時に少しでもシーン遷移を軽くする方法を個人的備忘録も兼ねて書き残しておきます。


スポンサーリンク

このサイトをシェアする