10. セキュリティ

10.1. 概要

NEXは、MD5でのパケット改ざんチェック機能と、 256ビットArcFour共通鍵アルゴリズムによる 暗号化機能を備えます。

パケット改ざんチェック機構は、すべての通信で有効であり、 暗号化はデフォルトではゲームサーバーとの通信のみ有効となっております。 パケット改ざんチェックはパケット受信時に行われ、 不正なパケットは破棄されるためアプリケーションまで上がってくることはありません。

インターネット通信の場合には、 P2P 通信のパケット改ざんチェックのセキュリティ強化のために、 マッチメイク時にゲームサーバーから配布される署名キーをアプリケーションから NetZへ設定する必要があります。

10.2. P2P 通信のパケット改ざんチェック

NetZの P2P 通信のパケット改ざんチェックには、アプリケーションから署名キーを 設定する必要があります。

ローカル通信の場合は、アプリケーション共有キーをNetwork::SetP2PDataPacketDefaultSignatureKey() で設定します。設定されない場合には、NEX内部のデフォルトのキーが署名に利用されます。

インターネット通信の場合は、マッチメイク時にゲームサーバーからのマッチメイク セッション共有の256ビットキーが通知されるので、Session::CreateSession(), Session::JoinSession()より前に、このキーを設定する必要があります。 この際、Network::SetP2PDataPacketDefaultSignatureKey()で設定された値は無視されます。

セッション共有のキーは、 MatchmakeSession::GetSessionKey()、 MatchmakeExtensionClient::CreateMatchmakeSession()、 MatchmakeExtensionClient::JoinMatchmakeSession() にて取得できます。 この共有キーを、Network::SetP2PDataPacketSessionSignatureKey()で設定します。

注意

インターネット通信の場合に、セッション共有キーを設定せずに、 Session::CreateSession(), Session::JoinSession()を実行すると、 実行に失敗しassertエラーが発生します。

10.2.1. アプリケーションでの実装例

Code 10.1 P2Pのアプリケーション共有署名キー設定
//P2P部分の署名用のキーです。アプリケーションごとに変更する必要があります
static qByte SIGNATURE_KEY[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};

// P2P部分の署名キーを設定します
nn::nex::Network::GetInstance()->SetP2PDataPacketDefaultSignatureKey
        (SIGNATURE_KEY, sizeof(SIGNATURE_KEY));
Code 10.2 P2Pのセッション共有署名キー設定
nn::nex::ProtocolCallContext oContext;
nn::nex::AutoMatchmakeParam autoMatchmakeParam;
nn::nex::MatchmakeSession joinedMatchmakeSession;
//...省略...

// マッチメイクセッションに参加する
matchMakingClient.AutoMatchmake(&oContext, autoMatchmakeParam, &joinedMatchmakeSession);
oContext.Wait();
//...省略...

// P2P セッションの署名キーとして、ゲームサーバーから通知されたキーを設定することにより、
// セッションごとに異なる署名を生成する
nn::nex::Network::GetInstance()->SetP2PDataPacketSessionSignatureKey(joinedMatchmakeSession.GetSessionKey());

10.3. P2P セッションの暗号化

NetZの P2P セッションは、デフォルトで暗号化されません。 アプリケーションで暗号化をStreamSettings::SetIsEncryptionRequired() で有効にして、キーをStreamSettings::SetEncryptionKey()で設定することにより暗号化されます。

キーとして、インターネット通信の場合は、マッチメイク時にゲームサーバーからのマッチメイク セッション共有のキーが通知されるので、そのキーを暗号キーとして用います。

注意

暗号化は、Session::CreateSession(), Session::JoinSession()より前に、キーを設定して有効とする必要があります。 必要とあれば、 NetZ::Terminate() 処理完了後に無効にできます。 Session::CreateSession() , Session::JoinSession() より後や、 NetZ::Terminate() 処理完了前に操作しようとした場合は、Assertで強制終了もしくは、 更新に失敗します。

10.3.1. 内部実装仕様

暗号化の実装は、リライアブル通信とアンリライアブル通信で異なります。

リライアブル通信は、ユーザーから設定された最大256ビットのキーに、 セッションごと異なるIDを加算したキーにより、ストリーミング暗号化されます。 よって、暗号化系列は、セッションごとに異なります。

アンリライアブル通信は、240ビットの鍵と、16ビットのシーケンス番号をIV(初期化ベクトル)として 連結したキーにより、ペイロード単位で暗号化されます。シーケンス番号が一周する(65536回送信する)と、 同じ暗号化系列が用いられることなります。 暗号化強度は、リライアブル通信に比べて劣るので、 永続的なゲームの内部データを送信する場合には、リライアブル通信を用いてください。 240ビットの鍵は、リライアブル通信と異なるように内部で生成し、セッションIDを加算した鍵を用います。

10.3.2. アプリケーションでの実装例

Code 10.3 P2P セッションの暗号化キーの設定
nn::nex::ProtocolCallContext oContext;
nn::nex::AutoMatchmakeParam autoMatchmakeParam;
nn::nex::MatchmakeSession joinedMatchmakeSession;
//...省略...

// マッチメイクセッションに参加する
matchMakingClient.AutoMatchmake(&oContext, autoMatchmakeParam, &joinedMatchmakeSession);
oContext.Wait();
//...省略...

// P2P セッションを暗号化する
nn::nex::Stream::GetSettings().SetIsEncryptionRequired(true); // 暗号化を有効にする
nn::nex::Stream::GetSettings().SetEncryptionKey(joinedMatchmakeSession.GetSessionKey()); // 暗号鍵をセットする