UnityでDigest認証を突破する!!

経緯...


Unityで通信対戦型のゲームを作ろうかと思いたち、色々調べてみたが既存の用意された環境での説明ばかりで、自分の欲しい情報が得られなかったため、ここに残します。

環境

サーバ: python[Flask]
クライアント: Unity[2019.3.2f1]

実際のコード

まず初めに、登録されたデータベースを参照し、
検索結果から該当するユーザーのみログイン可能にしたかったので、テスト用に簡易なデータベースを用意した。
使ったデータベースは、解読性を重視して、
SQLiteではなく、tinydbと言うドキュメント指向のデータベースを利用しました。
(個人的に昔から使ってて処理がほぼ確立していて楽なのでw 使用段階は「開発やテスト」段階の未だデータベース設計が仮状態の時です)

また、サーバ側のDigest認証方法は、Flask-HTTPAuthを利用して実現させています。そのため、Digest認証で解説されている認証アルゴリズムだと正常に認証が行えないため、Flask-HTTPAuthの実際のコードから解析を行い、認証結果を実現させています。

さらに、Digest認証には、MD5(非推奨?)でハッシュ値を認証していて、Unity側にも実装しなきゃいけない為、参照したサイトがあります。
MD5変換の詳しい解説は、そちらをご参考ください。

データベース内の情報

# account_tinydb.json

{"_default":{"1":{"username":"user","password":"password"}}}

現行、データベース内は平文で登録されている未だ内決めしていない為、
これは今後、設計する上で暗号化され保存される。
遊んでもらう相手がスーパーハッカーじゃない限り、解読不可だろうから...
今回はクライアント側がUnityなので、認証用のコードをそのまま埋め込む予定である。
webサイトの場合は、また違った方法で認証を実装しています。それは、また今度。

Server側のコード[python]

# app.py
import json
import os
from uuid import uuid4

from flask import Flask, g
from flask_httpauth import HTTPDigestAuth
from tinydb import Query, where, TinyDB as tydb

app = Flask(__name__)

#実行毎にシークレットキーが変わってしまうので、環境などに合わせて、ランダムで決めた固定値でもいいと思う。
app.config['SECRET_KEY'] = ''.join(str(uuid4()).split('-'))

auth = HTTPDigestAuth()

ACC_TYDB = f'data_base/account_tinydb.json'

def account_check(username):
   user = {}
   try:
       with tydb(ACC_TYDB) as db:
           que = Query()
           user= db.search(que.username == username)[0]
       return { user["username"]:user["password"] }
   except:
       return user

@auth.get_password
def get_pw(username):
   print(username)
   users = account_check(username)
   if username in users:
       return users.get(username)
   return None

@app.route('/')
@auth.login_required
def index():
   return json.dumps({'authenticate': 'success'})

if __name__ == '__main__':
   app.run()

サーバ側の実装は、あくまでもログインが今回は、目的なのでFlask-HTTPAuthの書いている例をそのまま使いまわしています。


python Unity側のコード

ここから先は

4,945字 / 1画像

¥ 100

期間限定!Amazon Payで支払うと抽選で
Amazonギフトカード5,000円分が当たる

この記事が気に入ったらチップで応援してみませんか?