技術の犬小屋

Webプログラミングを餌に生きる犬のメモ帳

ソーシャルゲームの通信をセキュアにする方法について、昔学習したことを忘れないうちに記事に起こすことにした。
 

ハッシュ認証

ソーシャルゲームなどで不正防止を行う為に認証を設けたい場合、ハッシュ値を用いた認証方法が挙げられる。
 
ハッシュ認証は、クライアントとサーバーの両方でハッシュ値を生成し、通信時にお互いのハッシュ値を照合することで通信の正当性を確認する。
 
ハッシュ値の元になる情報には、秘密鍵・ユーザーエージェント・パラメータなどを含める。
 
ハッシュ値を生成する為のハッシュ関数には複数の種類があり、2013年10月現在ではSHA-2のSHA-256がデファクトスタンダードとなっている。
 

SHA-2とは


任意長の原文から固定長の特徴的な値である「ハッシュ値」を求める計算手順(アルゴリズム)の標準規格の一つ。
2001年に米国家安全保障局(NSA)が開発し、米国立標準技術研究所(NIST)が標準に採用したSHA-224、SHA-256、SHA-384、SHA-512の4つをまとめた総称で、これらの末尾の数字がそれぞれのハッシュ値のビット長を表している。最長のSHA-512が最も安全性が高く、一般的にはSHA-256が最もよく利用されている。
それまで標準だった160ビットのSHA-1はコンピュータの性能向上と効率の良い攻撃方法の発見により十分安全ではなくなったため、より安全性の高いSHA-2への移行が推奨されている。

 
 
説明だけではイメージが湧きにくいので、イメージしやすいように、ハッシュ値で認証を行うPHPのコードを書いてみた。
 

<?php
/*
* ハッシュ認証を行うサーバサイドプログラム
*/
//秘密鍵
$SECRET_KEY = 'W4IyR8If75QVj3UHQ2jMdG';
//ユーザーエージェント名
$USER_AGENT = 'SmokyDogAPI';

//クライアントから送られてきたユーザに紐付けられている推測されにくい一意の値
$clientParam = $_POST['submit']['parameter'];
//クライアントから送られてきたクライアント側で生成したハッシュ値
$clientHash  = $_POST['submit']['hash'];

//秘密鍵・ユーザーエージェント・パラメータを繋げてサーバー側ハッシュ値生成
$serverHash = hash('sha256', $SECRET_KEY.$USER_AGENT.$clientParam);

if($clientHash === $serverHash){
    //認証成功
    //成功コードをクライアントに返す
    ……
}else{
    //認証失敗
    //エラーコードをクライアントに返す
    ……
}

 
 

クライアント側のコードを難読化する

ゲームで不正が行われる方法の一つとして、クライアントをデコンパイルし、ハッシュ認証に使う秘密鍵を盗む方法がある。それを防止する方法としてコードの難読化が挙げられる。
 
この記事だけではまとめきれないので、ここでは紹介まで。
 
 

ハードウェアのスペックも考慮する

私が以前に開発に関わったゲーム関係の案件では、SHA-2を採用せずに、あえてSHA-1を採用していた。
 
理由は、開発費用的な問題でハードウェア(サーバ)にあまり費用を割けなかったということ。
 
セキュリティは保ちつつ、システムに負荷をなるべくかけない選択肢としてSHA-1が挙がり、採用された。
 
 
以上
 
 
参考
私が昔書いたコード

DNSサーバの概要 arrow-right
Next post

arrow-left SSLについて
Previous post

コメントを残す