はじめに
このガイドでは、OZero Security のインストールから最初のセキュリティ機能適用までを段階的に案内します。セキュリティの専門知識がなくても、約3分で基本設定を完了できます。
目的から始める
今行いたい作業を選ぶと、このマニュアルの該当セクションまたは API リファレンスへ移動します。
概要
OZero Security は、一般的なハッキングツールがアクセスしにくい Native C++ レイヤーでセキュリティロジックを実行し、Unity ゲームを保護します。Unity エディター内のダッシュボードでモジュールを有効化するだけで、コアな保護機能が動作します。シーンの設定や追加のコード作成は必要ありません。
- ビルド整合性検査(アプリ改ざん検知)
- スピードハックおよびタイムハック検知
- メモリインジェクション監視
- 暗号化されたインゲーム変数型(Secure Types)
- 暗号化されたセーブファイルと PlayerPrefs
- 有効化された検出器は SDK 開始時に自動的に準備されます。シーンに別のオブジェクトを配置したり、繰り返し初期化コードを記述したりする必要はありません。
- セキュリティ設定はビルド処理中に保護され、一般プレイヤーの配布物に平文の設定が露出することはありません。
- Native C++ ランタイムガードが、管理された Unity コードの外側で追加の検証レイヤーを提供します。
- 検知結果はコールバック、ログ、Pro テレメトリで確認できるため、テストや運用中に原因を追跡しやすくなります。
1
パッケージのインポート
Unity エディターを開き、OZero Security パッケージをインポートします。Unity Package Manager を使用するか、.unitypackage ファイルをダブルクリックしてインポートできます。
Import Unity Package ダイアログが表示されたら、すべての項目がチェックされた状態で Import をクリックしてください。必要なスクリプト、ネイティブプラグイン、エディターツールが自動的に追加されます。
2
ダッシュボードを開く
インポートが完了したら、Unity のメニューバーから Config Dashboard を開きます:
Config Dashboard が開くと、この画面でプリセット、セキュリティモジュール、ライセンス、ビルド整合性設定を一度に管理できます。Project ウィンドウでファイルを直接探して修正する必要はありません。
Unity エディターメニューの説明
OZeroSecurity は、設定ウィンドウを Window > OZero Security、診断や bake コマンドを Tools > OZero Security に配置しています。セキュリティプリセットは Config & Dashboard から適用する設計です。保存前に変更後の設定を確認できます。
| メニュー | 役割 | 使用タイミング |
|---|---|---|
| Window > OZero Security > Config & Dashboard | メインの OZeroSecurityConfig アセットを開く、または作成します。 | プリセット適用、モジュール有効化、対応ポリシー設定、ビルド整合性設定の確認を最初にここで行います。 |
| Window > OZero Security > License Settings | OZeroLicenseConfig を開く、または作成します。 | Standard / Pro のライセンス設定、サーバーエンドポイント、テレメトリオプションを入力するときに使用します。 |
| Window > OZero Security > Check Setup | プロジェクトとリリース設定でよく発生する問題をエディター上で診断します。 | パッケージのインポート直後、リリースビルド前、またはモジュールが期待どおり動作しない場合に実行します。 |
| Tools > OZero Security > Check Integrity Manifest | OZero 整合性マニフェストを開き、デコードされた内容を確認します。 | ビルド整合性のトラブルシュートやサポート調査でマニフェスト内容を確認するときに使用します。 |
| Tools > OZero Security > Bake Security Config Blob | 保護されたセキュリティ設定 blob を StreamingAssets に再生成します。 | 高度なデバッグまたは CI ワークフローで使用します。通常のプレイヤービルドでは自動的に bake されます。 |
| Tools > OZero Security > Bake Assembly Hash | 直近のビルド出力に対して oz_ahash.bin を再生成します。 | フルビルドパイプラインを再実行せず、コードだけを再ビルドした場合にのみ使用します。 |
| Tools > OZero Security > Keystore SHA Extractor | Android keystore から SHA-1 と SHA-256 fingerprint を抽出します。 | Build Integrity の Android 署名 fingerprint を入力するときに使用します。 |
| Tools > OZero Security > Add Debug SHA Key to Config | Android debug keystore を探し、その SHA-256 fingerprint を config に追加します。 | ローカル Android デバッグビルドでのみ使用します。リリースビルドではリリース署名キーの fingerprint を使用してください。 |
| Tools > OZero Security > Steam Anti-Piracy > Scan Steam Redistributable | PC ビルドまたはプラグインフォルダー内の Steam redistributable ファイルと既知の emulator artifact をスキャンします。 | Steam リリースのパッケージング前、または疑わしい Steam ファイルが含まれていないか確認するときに使用します。 |
| Tools > OZero Security > Check Time.timeScale Usage | OZero の時間保護と競合する可能性がある直接的な Time.timeScale 書き換えコードをスキャンします。 | リリース前、または Speed & Time Hack モジュールがプロジェクト側の time-scale ポリシー問題を報告した場合に実行します。 |
3
モジュールの有効化
ダッシュボード内でセキュリティモジュールの一覧とトグルスイッチを確認できます。使用するモジュールを有効化してください。以下は推奨される開始設定です。
セキュリティのプリセットを選択する
まずプリセットを選択した後、プロジェクトに合わせて個別のモジュールだけ調整してください。一般的なライブゲームは Standard から始めることをお勧めします。保護のレベル、パフォーマンス、誤検知の可能性のバランスが最も良いです。
| プリセット | 推奨される使用先 | 適用されるポリシーの要約 |
|---|---|---|
| Low | プロトタイプ、開発ビルド、初期の QA | 軽い核心の検査だけ維持します。テストの環境が早すぎる段階でブロックされないよう、プラットフォームネイティブ検査と強制終了のポリシーを緩和します。 |
| Standard | ほとんどのリリースゲームに推奨されるデフォルト値 | 核心保護のセット、開始の際の検証、ランタイムの再検証、エミュレーターの検査、推奨される IL2CPP ファイルのカバレッジをオンにします。互換性と保護のレベルのバランスを合わせた構成です。 |
| Strict | リスクの高いライブサービス、PvP、対戦型のビルド | 最も広いカバレッジを適用し、より多くの失敗を致命的な違反として処理します。プラットフォーム、署名、ストア配布フローを十分にテストした後に適用してください。 |
| モジュール | 機能説明 | 推奨有無 |
|---|---|---|
| Build Integrity Validator | アプリバイナリの改ざんの有無を検知 | 推奨 |
| Speed Hack Detector | 時間操作チート検知 | 推奨 |
| Injection Detector | メモリフッキングツールの監視 | 推奨 |
| Install Source Validator | 不正な APK のブロック(Android 専用) | 選択 |
ダッシュボードで使用するモジュールをオンにし、OZeroSecurityConfig アセットを保存するだけです。プレイヤーが起動すると、SDK が有効化されたモジュールを自動的に準備します。
ライセンスモデル — Standard / Pro
Standardはサーバー連携なしでローカル保護を提供します。Proはプロジェクト専用ネイティブバイナリ(Native Variant)とマニフェストのバインディングに、テレメトリー・署名付き時刻・リモートセキュリティ設定・アテステーション・サーバー検証を組み合わせます。
| 項目 | Standard | Pro |
|---|---|---|
| ライセンスキー | — (なし) | OZ-PRO-XXXX ×6 |
| ブート時のネットワーク | 必要なし — オフライン実行可能 | デバイスあたり POST /v1/activate 1回の後キャッシュ |
| 10個の保護モジュール | 10個の保護モジュール全体を活性化 | 10個の全体 (Standard と同一) |
| ネイティブ Variant | 共用のネイティブモジュール | 含む |
| クラウドのテレメトリー | 送信しない | オン — 脅威イベントを /v1/telemetry に送信 |
| 署名された時間 (時計の操作防止) | オフ — WebTime は HTTPS HEAD のみ使用 |
オン — 署名された /v1/time 応答を使用 |
| デバイスあたりの限度 | 無制限 (キーなし、強制なし) | デフォルト 5台 / 調整可能 |
| ソースコードのアクセス | 管理型の C# のみ | 管理型の C# のみ |
OZeroLicenseConfigでProのサーバー機能を設定してください。
Proライセンスキーの登録
Standardは個別のライセンス設定なしで動作します。ProではUnityでOZeroLicenseConfigアセットを作成し、プロジェクトのキーを入力します。専用Variantのバインディングとランタイム有効化・サーバー機能に使用します。
1. 設定アセットの作成
Unity の上部メニューから Window → OZero Security → Config & Dashboard を開きます。License & Server セクションで Create OZeroLicenseConfig ボタンをクリックしてください。このボタンを使うと、OZeroLicenseConfig アセットが正しい Resources/ フォルダーに自動作成されます。フォルダーを手動で作成したり、アセットを移動したりする必要はありません。
2. Inspector フィールドを埋める
| フィールド | 必須の可否 | 説明 |
|---|---|---|
| tier | すべてのティアー | Standardは共用ネイティブモジュールを使用します。Proはプロジェクト専用ネイティブバイナリ、サーバー有効化、テレメトリー、リモートセキュリティ設定を提供します。 |
| licenseKey | Pro | プロジェクトに発行されたOZ-PRO-...形式のProライセンスキーです。専用バイナリのプロジェクトとの対応を確認し、サーバー有効化とProサーバー機能にも使用します。 |
| allowStandardBuildWithPremiumLicense | Pro | 明示的な native variant 互換性オーバーライドです。通常のビルドでは無効のままにしてください。Pro ライセンスのプロジェクトを Standard public native モジュールでビルドする場合、または Standard 設定で Pro private native variant パッケージを意図的にビルドする場合だけ有効にします。Standard public variant ビルドは、このオプションが有効でもキーなしで動作します。Standard + private variant ビルドでは一致するライセンスキーの入力が必要で、ビルド/ランタイム検証では signed manifest、license key hash、project identity、native hash を引き続き確認します。 |
| appIdentifier | 自動送信 | Pro 有効化リクエストを送るとき、SDK は Unity の Application.identifier を一緒に送信します。Customer Portal に登録された Bundle ID または Package Name とこの値が一致しない場合、有効化が拒否されることがあります。まず Unity Player Settings の Identifier を確認してください。 |
| serverBaseUrl | Pro runtime | Proの有効化、テレメトリー、署名付き時刻、アテステーション、サーバーポリシーに使用するサーバーアドレスです。サーバーレスモードでは呼び出しません。別途案内がなければhttps://api.ozerosecurity.comを維持してください。 |
| serverPublicKeyHex | Pro runtime | カスタマーポータルのServer Keyに表示されるProサーバー署名公開鍵です。サーバー応答の署名を検証します。専用バイナリのマニフェストは、このフィールドではなくSDK内蔵のバイナリ署名鍵で検証します。 |
| previousServerPublicKeyHex | Pro 任意 | Proサーバー署名鍵の切り替え中に使用する旧公開鍵です。サポートから切り替えの案内があった場合のみ入力し、通常は空欄にしてください。 |
| tokenTtlSeconds | Pro runtime | Pro 有効化が一度成功したあと、オフライン状態でその結果を何秒間使えるかを決めます。既定値 604800 は 7 日です。この時間を過ぎてもローカル保護は動作しますが、テレメトリーや signed time などの Pro サーバー機能は次の有効化が成功するまで無効になります。 |
| offlineProPolicyMode | Pro | デバイスがオフラインのとき、ローカル Build Integrity が署名済みポータルブロックポリシーをどう使うかを決める Pro オプションです。ApplyCachedBlockPolicies は有効なキャッシュポリシーがある場合だけ適用する fail-open の既定値で、多くのライブゲームに推奨します。RequireFreshPolicy は使用可能な署名済みポリシーがなく、サーバー Integrity が有効な場合に fail-closed で扱います。IgnoreCachedBlockPolicies はテストや移行のためにキャッシュポリシーをバイパスします。各値の意味は OZeroOfflineProPolicyMode で確認できます。 |
| activationTimeoutSeconds | Pro runtime | Pro 有効化リクエストである /v1/activate の応答を最大何秒待つかを決めます。既定値は 6.0 です。この時間を超えてもシーンロードは止めません。利用できる Pro キャッシュがあればそれを使い、キャッシュがなくても選択したサーバー機能だけが利用不可になり、ローカル保護は継続します。 |
| enableLog | 選択 | 有効にすると、ライセンスキャッシュの使用、有効化成功、タイムアウト、署名不一致などの流れを OZeroSecLog に出力します。連携中は有効にしておくと問題を見つけやすく、リリースビルドでログを減らしたい場合は無効にできます。 |
| Pro サーバー機能 | ||
| enableDevicePolicyHeartbeat | Pro | 現在の端末が Customer Portal でブロックされていないかを、Pro サーバーに定期的に確認します。サーバーが DEVICE_BLOCKED を返すと、SDK は保存済みの Pro 権限情報を削除し、アプリ実行をブロックします。 |
| devicePolicyHeartbeatInterval | Pro | 端末ブロック状態を確認する基本間隔です。既定値は 300 秒です。0 にすると定期確認を行いません。 |
| devicePolicyHeartbeatJitterPercent | Pro | 多くの端末が同じ瞬間にサーバーへアクセスしないよう、確認間隔に少し差をつける割合です。既定値 20 は、設定された間隔の前後に少し時間をずらすという意味です。入力範囲は 0〜75 です。 |
| enableSecurityLevelCheck | Pro | 有効にすると、アプリ起動時に /v1/security-level でこのビルドのセキュリティ設定をサーバーに確認します。ポータルで要求される最低レベルより低い場合、サーバーが拒否することがあります。既定値は false です。 |
| declaredSecurityLevel | Pro | このビルドがサーバーへ報告するセキュリティレベルです。既定値は Standard です。Low はプロトタイプや内部テストに使用し、Strict は強いポリシーで通常ユーザーがブロックされないことを QA で確認したあとに使用してください。 |
| failOnSecurityLevelReject | Pro | 有効にすると、サーバーがセキュリティレベルまたは設定ハッシュを明確に拒否した場合、アプリのブロックフローを実行します。単純なネットワークエラー、サーバーメンテナンス、ライセンス点検状態は改ざん扱いにせず、Pro サーバー機能だけを無効にします。 |
| securityLevelCheckInterval | Pro | アプリ実行中にもセキュリティレベルを再確認するかを決める間隔です。既定値 0 は、アプリ起動時に一度だけ確認するという意味です。 |
| securityLevelCheckJitterPercent | Pro | 多くの端末で再確認タイミングが重ならないよう、セキュリティレベル確認間隔に少し差をつける割合です。既定値は 20、入力範囲は 0〜75 です。 |
3. ビルド & 検証
追加のコードを書く必要はありません。アプリが起動すると、SDK が OZeroLicenseConfig アセットを自動的に読み込みます。初回実行後、Player ログで [OZeroLicense] activated; tier=pro caps=5 のような行を確認してください。Pro に設定したのに Standard モードと表示される場合は、まずアセットの場所と名前を確認します。アセットは Resources/ フォルダー配下にあり、名前は正確に OZeroLicenseConfig である必要があります。
オフラインの動作
要点から言うと、ネットワークが切れてもゲームとローカル保護は止まりません。Standard はもともとサーバーを使わず、Pro も同じオフラインのローカル保護を維持します。明示的に選択したサーバー機能だけが、一定期間保存済みの認証情報を使えます。
Standard — インターネットなしで起動
Standard はサーバーに許可を確認しません。アプリに含まれるローカル保護モジュールだけを実行するため、プレイヤーがオフラインでもゲームは起動します。テレメトリーや signed time など、Pro サーバーが必要な機能だけが使われません。
Pro — ローカル保護はオフライン継続、選択したサーバー機能はキャッシュを使用
任意の Pro サーバー機能を有効にした場合、オンライン時に端末とライセンスを確認します。選択したサーバー機能は、一定時間だけ一時的な切断に耐えられます。この確認は、取得済み Native Variant のビルドやローカル保護を制限しません。
tokenTtlSeconds は保存されたサーバー機能結果の有効期間で、既定値は 604800 秒、つまり 7 日です。オフライン中に期限切れになると、テレメトリー送信や signed-time 検証などのサーバー依存機能だけが次のアクティベーション成功まで利用できなくなります。ゲーム、取得済み Native Variant、ローカルディテクターはそのまま継続し、SDK が製品ティアを Standard に暗黙的に切り替えることはありません。
Pro — ポータルでブロックしたビルドはオフラインでも止める
一時的なサーバー障害やネットワーク障害で基本保護として起動を続けることと、運営者がポータルで明示的にブロックしたビルドを許可することは別の問題です。Pro 認証が成功すると、サーバーはブロック対象のビルドハッシュ、SDK バージョン、アプリバージョンなどを署名付きリストとして返します。SDK はこのポリシーを一時的なサーバー機能状態とは別に扱います。
この動作は Config Dashboard の License & Server セクションにある OZeroLicenseConfig.offlineProPolicyMode で設定します。デバイスがサーバーに接続できないとき、ローカル Build Integrity が最後に受け取った署名済み Pro ポータルブロックポリシーをどう扱うかを決めます。
| モード | 使用基準 |
|---|---|
| ApplyCachedBlockPolicies | 多くのライブゲームに推奨する既定値です。有効な署名済みポリシーキャッシュがあれば、ポータルでブロックしたビルドやバージョンをオフラインでも引き続きブロックします。逆にキャッシュがない、削除された、または期限切れの状態でデバイスがオフラインの場合、このポリシーゲートはビルドを失敗させずに通過します。 |
| RequireFreshPolicy | オンライン中心のゲーム向け strict モードです。初回起動、再インストール、キャッシュ削除、キャッシュ期限切れなど、使用可能な署名済みポリシーがない場合は、古いまたは存在しないポリシーを信頼せず Build Integrity を失敗として扱います。この fail-closed 動作にはサーバー Integrity オプションの有効化が必要です。 |
| IgnoreCachedBlockPolicies | テストや移行のための bypass モードです。オフライン中はキャッシュ済みポータルブロックポリシーを読まないため、このゲートではポータルブロックルールが適用されません。ライブサービスビルドには推奨しません。 |
要約すると、ApplyCachedBlockPolicies は運用既定の fail-open モード、RequireFreshPolicy は fail-closed ポリシーモード、IgnoreCachedBlockPolicies はテスト用 bypass です。毎回の検証でオンラインサーバー確認を必須にしたい場合は、このオプションだけに依存せず、サーバー Integrity または Managed Verification の必須オプションも一緒に設定してください。
ApplyCachedBlockPolicies では、完全なオフライン初回起動、再インストール、キャッシュ削除、キャッシュ期限切れの状態でポータルブロックポリシーを適用できません。そのような場合にも有効な署名済みポリシーを必須にしたい場合は、RequireFreshPolicy とサーバー Integrity を一緒に使用してください。
| 状態 | ディテクター | テレメトリー | Signed Time |
|---|---|---|---|
| オンライン、ちょうど活性化 | 10個の全て On | On | On |
| オフライン、保存済み Pro 情報が有効 | 10個の全て On | Off (オフラインイベントは保存しない) | 可能な場合は WebTime を代替使用 |
| オフライン、保存済み Pro 情報が期限切れ | 10個の全て On | Off (次のオンライン認証まで) | Off (次のオンライン認証まで) |
| 初回起動 + 完全オフライン | 10個の全て On | 最初のオンライン実行まで Off | 最初のオンライン実行まで Off |
ライセンス問題の解決
問題が起きたら、まず Unity Player ログで [OZeroLicense] を検索してください。このログで、SDK が Standard として起動したか、Pro 認証が成功したか、失敗した場合になぜ Standard へ下がったかを確認できます。セキュリティイベント送信の問題は [OZeroTelemetry] も一緒に検索してください。
| ログに表示される内容 | 意味 | 対応方法 |
|---|---|---|
[OZeroLicense] Standard / serverless mode. |
SDK が Standard モードで起動しました。 | Standard を使う予定なら正常です。Pro を期待している場合は、Unity メニュー Window → OZero Security → Config & Dashboard で作成した OZeroLicenseConfig.asset が Resources/ 配下にあるか確認してください。名前は正確に OZeroLicenseConfig で、tier=Pro と licenseKey も入力されている必要があります。 |
Pro->Standard downgrade: /v1/activate returned LICENSE_NOT_FOUND |
サーバーがライセンスキーを見つけられない、または現在使用できない状態です。 | licenseKey を Customer Portal に表示されるキーともう一度比較してください。大文字小文字とダッシュはそのままにします。ポータル上の状態が pending、suspended、revoked、expired の場合、Pro 認証は成功しません。 |
ANDROID_BUNDLE_ID_MISMATCH / WINDOWS_PRODUCT_NAME_MISMATCH |
現在のビルドのアプリ情報が、ポータルに登録された値と異なります。 | Android/iOS は Player Settings の Application.identifier、Windows は Company/Product 名、WebGL は実行 origin を確認してください。ポータルの登録値と違う場合、/v1/activate は拒否されます。値を変更した後は、新しいビルドで再テストしてください。 |
activation token signature verification failed |
サーバー応答は届きましたが、SDK がその応答を信頼できないと判断しました。 | これは Pro アクティベーションだけで確認する項目です。Customer Portal > Server Key の Active publicKey を OZeroLicenseConfig.serverPublicKeyHex に入力してください。ポータルに kid が一緒に表示されても、Unity には 64 文字の hex publicKey だけを入れます。値が正しいのに失敗する場合は、企業プロキシや MITM 機器を通らない直接ネットワークで一度テストしてください。 |
private native variant manifest signature is invalid |
Variant パッケージの manifest が無い、編集された、または信頼済みの OZero Variant signing key で署名されていません。 | これは serverPublicKeyHex を入力して直す問題ではありません。Pro Variant パッケージは、割り当てられたパッケージを再ダウンロードし、manifest と native plugin ファイルを同じパッケージ由来のまま使ってください。新しく取得したパッケージでも失敗する場合は、manifest ファイルと Unity ビルドログを OZero サポートへ送ってください。 |
DEVICE_BLOCKED |
この端末は Customer Portal でブロックされています。 | ポータルでその deviceId のセキュリティイベントを確認してください。実際の攻撃やポリシー違反ならブロックを維持し、QA 端末や誤検知ならポータルで解除します。SDK はこの応答を受け取ると保存済み Pro 権限を消去し、ブロック処理を実行します。 |
ACTIVATION_LIMIT |
このライセンスで新しく認証できる端末数を超えました。 | ポータルで不要になったテスト端末を整理してください。実ユーザーの増加が原因なら、ライセンスの端末上限を増やす必要があります。 |
/v1/activate timed out / network error |
サーバーに接続できない、または応答が遅すぎます。 | 端末が https://api.ozerosecurity.com/health に接続できるか確認してください。社内ファイアウォール、プロキシ、DNS も確認します。遅延が大きい地域では activationTimeoutSeconds を少し増やしてテストしてください。保存済み Pro 情報があれば、SDK はそれを先に使用します。 |
cached entitlement past TTL; clearing. |
保存済み Pro 情報の有効期間が切れました。 | 端末が tokenTtlSeconds より長くオフラインだと、保存済み Pro 情報は信頼されなくなります。ゲームは Standard レベルで継続し、次のオンライン認証に成功すると Pro 機能が戻ります。長期オフラインプレイが多いゲームでは TTL を増やせます。 |
SERVER_NOT_CONFIGURED / SIGN_FAILED |
サーバーが認証トークンに署名できませんでした。 | 多くの場合、クライアント設定ではなくサーバー側の Server Key または暗号化キー状態の問題です。Customer Portal の Server Key 状態を確認してください。本番サーバーで発生した場合は、ログ時刻、licenseKey の一部、発生プラットフォームを OZero サポートへ伝えてください。 |
enableLog をオフにすることを推奨します。QA には便利ですが、一般ユーザー向けビルドにティア、機能状態、検知フローの詳細を残す必要はありません。
プロジェクト設定
個別のセキュリティモジュールを調整する前に、ネイティブプラグインとストアのビルド、プラットフォームの検証に影響を与える Unity Player Settings を先に確認してください。
最小のビルドターゲット
| プラットフォーム | 最小のターゲット | 説明 |
|---|---|---|
| Unity Editor | 2022.3 LTS+ |
OZero Security SDK 1.0.5 は Unity 2022.3 LTS 以上が必要で、Unity 6 も検証済みです。2021.3 のプロジェクトはパッケージをインポートする前にアップグレードしてください。 |
| iOS | 14.0+ |
iOS ビルドでは Project Settings > Player > iOS > Target minimum iOS Version を 14.0 以上に設定してください。ABI 21 のインジェクション検知器は Apple のシステムイメージと注入コードを区別するのに iOS 14 の shared-cache API を使うため、それ未満では Editor の preflight が失敗します。 |
| Android | API 24+ |
Android ビルドは Project Settings > Player > Android > Minimum API Level を Android 7.0 Nougat (API level 24) 以上に設定してください。ストアのリリースビルドは IL2CPP と ARM64 の使用を推奨します。 |
PrivacyInfo.xcprivacyが含まれます。Unityのpost-processがiOS XcodeアプリtargetとmacOSのContents/Resourcesに追加します。OZeroはアプリ内のSDK状態にUnity PlayerPrefsを使用するため、UserDefaultsのCA92.1理由を宣言します。最終アプリにマニフェストを保持し、提出前にXcode privacy reportを確認してください。
リリースビルド向けのセキュリティと容量最適化設定
最終リリースビルドを公開するときは、ビルドを強化しアプリ容量を減らすために、次の Unity 設定を推奨します。
セキュリティ強化(IL2CPP 設定): Android、iOS など Unity が対応する環境では、ビルド方式を IL2CPP にしてください。IL2CPP はリバースエンジニアリングを完全に防ぐものではありませんが、C# コードやメタデータがそのまま露出する範囲を減らし、OZero のセキュリティチェックがより堅いリリース環境で動作する助けになります。パス: Project Settings > Player > Other Settings > Scripting Backend
容量最適化(Managed Stripping 設定): 使用していない managed code を削除してアプリ容量を減らす機能です。最初から強く削りすぎるとアプリが実行時に失敗する可能性があるため、まずは Low または Medium から始めてください。
注意: 設定を変更した後は、シーン遷移、データ保存、Addressables、決済や広告などの外部 SDK が実機で正しく動作することを確認してから、stripping level を上げてください。
Android ProGuard / R8 の設定
OZero Security は別途の Java SDK パッケージを要求しません。ただし、Android リリースビルドで Minify、ProGuard、R8 を有効にした場合は、Unity Java ブリッジとプロジェクトで使用するカスタム Android ブリッジクラスを保持する必要があります。そうすることで、パッケージ情報、インストール元、APK 署名証明書チェック、ブートアセットロードに必要な JNI 呼び出しが難読化以降も安定して動作します。
proguard-user.txt に追加してください。Minify を使用しない場合、別途の ProGuard 設定は必要ありません。
# OZero Security - Unity Android ProGuard/R8 keep rules
-keep class com.unity3d.player.UnityPlayer { *; }
-keep class com.unity3d.player.UnityPlayerActivity { *; }
-keep class com.unity3d.player.UnityPlayerGameActivity { *; }
-keep class com.unity3d.player.UnityPlayerForActivityOrService { *; }
-keepattributes *Annotation*,InnerClasses,EnclosingMethod,Signature
# If your game adds custom Java/Kotlin bridge classes that OZero or your code
# calls through AndroidJavaClass / AndroidJavaObject, keep those classes too.
# Replace the package below with your own bridge package.
# -keep class com.yourcompany.yourgame.bridge.** { *; }
libOZeroSecurity.soを名前変更、削除、再パッケージ化しないでください。プラグインはAssets/OZeroSDK/Plugins/Android/arm64-v8aの下に維持し、32ビットビルドを配布する場合はarmeabi-v7aも一緒に維持してください。- Build Integrity > Check Platform Native と Android SHA Keys を使用する場合は、Minify/R8 適用後の最終署名された APK または AAB で必ずテストしてください。デバッグキーストアのフィンガープリントとリリースキーストアのフィンガープリントは異なります。
- Minify をオンにした後にのみ、Android ログで JNI 照会失敗、インストール元検知失敗、APK 署名チェック結果が空と表示される場合は、まずカスタムブリッジの keep ルールを確認してください。
- ストア配布用のビルドは、IL2CPP、リリース署名、
Android Sha Keysに登録された予想される Android SHA-256 フィンガープリント、そして少なくとも1台の実際のデバイスでのクリーン実行テストを基準に検証してください。
5
OZeroSecurityConfig の設定
OZeroSecurityConfig ScriptableObject アセットはパッケージのインポート時に含まれます。Project ウィンドウで選択し、すべてのセキュリティモジュールの設定を確認および調整してください。ランタイムでは OZeroSecurityConfig.Instance としてアクセスします。
共通設定
すべてのセキュリティモジュールで共有される最上位設定です。この表のデフォルト値は、コードに定義されたシリアライズ初期値を基準にしています。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| developerSecret | string | "" | OZeroSV_File と OZeroSafePlayerPrefs のデータを保護するためのプロジェクト別 secret です。任意の文字列を手入力するのではなく、Config Dashboard の Generate Secure Secret ボタンで生成してください。ゲームごとに異なる値を使い、文書、ログ、公開リポジトリに出さないでください。リリース後にこの値を変更すると、古いビルドが保存した保護データを新しいビルドで復号できません。 |
| enableLog | bool | false | Enable Debug Logs をオンにすると、SDK 初期化、設定の読み込み、ライセンス/テレメトリの流れ、検知イベントなどの内部状態が Unity Console と Player ログに出力されます。開発/QA 段階で原因を特定するのに役立ちますが、検知フローやモジュールの状態が露出する可能性があるため、本番ビルドではオフにすることを推奨します。 |
| enableFailureDiagnostics | bool | false | Enable Failure Diagnostics をオンにすると、セキュリティ違反が発生した際にローカル診断ファイルを Application.persistentDataPath に保存します。ファイルにはモジュール名、ハッシュ、デバイスの状態、インストールパッケージ名、ランタイム設定の一部が含まれる可能性があるため、QA やカスタマーサポートセッションでのみオンにすることを推奨します。プラットフォームごとの既定の保存場所:
|
developerSecret を生成して保存してください。リリース後は変更しないでください。この値を変更すると、既存の OZeroSV_File と OZeroSafePlayerPrefs データを新しいビルドで復号できません。
Managed UI(全ライセンス)
Security Termination Notice、共通 dialog prefab、localization は Standard / Pro で利用できます。Pro では Build Integrity と Steam DRM 用の Managed Verification retry・timeout・provider 設定も表示されます。optional package の import 前に Package Manager から Unity UI と TextMeshPro を install してください。通知はすでに予約された終了を説明するだけで、終了の取消や native deadline の延長はできません。
OZeroBuiltIn の場合、または Pro Managed Verification が Built-In の場合は optional TMP package が必要です。不足すると build を停止します。Dedicated Server では Built-In UI を使用できないため Disabled または custom callback/logging を選択してください。graphical project は Window > OZero Security > Check Setup の Import Package で修復します。
securityUiLanguageCode、設定 fallback、英語の順で選択します。Managed Verification server の Reason 原文は表示しません。拡張には Tools > OZero Security > Localization > OZero Security UI Text を使用します。
RuntimeNoticeReady 後のみです。安全な OZ-SEC-* code だけを表示し、内部検知情報は公開しません。
oz_boot.bin が必要です。欠落、不正形式、未署名、不一致、または ABI 17 artifact は build/runtime failure です。oz_boot.bin は平文の環境フラグだけを含み、改ざん認証 artifact ではありません。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| securityTerminationNoticePolicy | enum | Disabled | 全ライセンス。runtime fatal event で通知なし、OZero Built-In、custom callback のいずれかを選択します。Low・Standard security preset は Built-In、Strict は Disabled です。初期 fail-close 経路には表示されません。 |
| securityUiDialogPrefabResourcePath | string | "" | 全ライセンス。project 所有 security dialog prefab の Resources path です。空の場合は optional TMP package の既定値を使います。旧 managedVerificationDialogPrefabResourcePath 値は自動移行されます。 |
| securityUiLanguageCode | string | auto | 全ライセンス。終了通知と Managed Verification UI の言語です。auto は Application.systemLanguage に従います。旧 managedVerificationLanguageCode 値は自動移行されます。 |
| securityUiFallbackLanguageCode | string | en | 全ライセンス。内蔵英語の安全文言より前に使用する fallback 言語です。旧 managedVerificationFallbackLanguageCode 値は自動移行されます。 |
| managedVerificationUiPolicy (Pro) | enum | BuiltInBlockingDialog | Pro Only 機能です。OZero Managed Build Integrity と Steam DRM の状態をユーザーへ表示する UI フローを選択します。内蔵のブロッキング/通知ダイアログには TextMeshPro と optional OZeroSecurity_BuiltInDialog_TMP.unitypackage の import が必要です。この package を import しない場合、または独自 UI に置き換える場合は Custom UI / Callback Only を使用してください。 |
| managedVerificationRetryTimeoutSeconds (Pro) | int | 15 | ユーザーが Retry を押した後、retry-timeout 状態へ移るまで待機する最大時間です。プレイヤーが無期限の検証待ちにならないようにします。 |
| managedVerificationOnlineRequiredTimeoutSeconds (Pro) | int | 120 | オンライン必須ダイアログを表示してから、設定された timeout action を適用するまで待機する最大時間です。 |
| managedVerificationTimeoutAction (Pro) | enum | BlockSession | 検証が時間内に復旧しない場合の動作を制御します。ダイアログを表示し続ける、保護セッションをブロックする、アプリを終了する、またはカスタムフロー用の callback のみ呼び出す、のいずれかを選択します。 |
| autoRetryManagedVerificationWhenNetworkRestored (Pro) | bool | false | ネットワーク接続が復旧した後に Managed Verification を自動で再試行します。明示的なプレイヤー操作なしで再試行しても安全なゲームフローでのみ有効にしてください。 |
Global Threat Response
セキュリティの脅威が確認されたときのゲームの反応を設定します。テスト中はコールバックとログを先に確認し、実際の配布ビルドではプレイヤーへの通知時間と終了ポリシーをプロジェクトの運用方法に合わせて選択してください。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| forceQuitOnDetection | bool | true | forceQuitOnDetection は、確定した脅威が検知されたときに SDK がゲームを自動終了するかどうかを決定します。オフにするとコールバックとログだけを確認でき QA には便利ですが、実際の配布ビルドでは迂回されたクライアントが実行を続ける可能性があるため、慎重に選択してください。 |
| fatalCallbackGraceSeconds | float | 10 | fatalCallbackGraceSeconds は、脅威検知後、ゲーム側のセキュリティコールバックがプレイヤーへの通知 UI を表示できる最大時間です。デフォルト値は 10 秒です。0 に設定すると、通知時間を置かずに即座に終了する以前の方式で動作します。 |
連携トラブルシューティング
OZero Security を有効化した後にアプリが終了する場合、または特定の環境でだけ問題が出る場合は、まずローカル診断ファイルでどのモジュールが反応したかを確認してください。推測で設定を変えるのではなく、ファイル内の module、subCode、reason を基準に下の表を順に確認します。
OZ-SEC-* サポートコードが表示された場合は、問い合わせに含めてください。ポップアップがないことは OZero が無関係である証拠ではありません。初期 fail-close、Boot-ACK・watchdog 終了、実際の crash、OS kill は UI より先に終了する場合があります。ozero_abort.txt、Player log、Check Setup、build preflight の結果を確認してください。Strict preset の通知既定値は Disabled です。
アプリが繰り返し終了する場合
| 手順 | 実施内容 | 確認方法 |
|---|---|---|
| 1 | Unity メニューの Window > OZero Security > Config Dashboard を開き、OZeroSecurityConfig の Key Common Settings > Enable Failure Diagnostics を有効にします。 | QA またはサポート中に原因を確認するときだけ使用し、公開リリースでは有効にしたまま配布しないでください。 |
| 2 | 追加で設定を変える前に、同じビルドで問題を一度再現します。 | 再現前に複数の設定を同時に変えると原因を追いにくくなります。まず現在の状態の診断ファイルを確保してください。 |
| 3 | Application.persistentDataPath にある最新の ozero_*_failure.log ファイルを開きます。 | Build Integrity は ozero_integrity_failure.log と、ozero_integrity_platform_native_failure.log のような詳細ファイルを同時に作る場合があります。アプリが非常に早い段階で終了して failure log がない場合は、ozero_abort.txt と Player log も確認してください。 |
| 4 | ファイルを収集したら、Enable Failure Diagnostics を再度オフにします。 | サポート手順で明示的に必要な場合を除き、公開リリースビルドで有効にしたままにしないでください。 |
よく見る診断項目
| 項目 | 意味 | 次に確認すること |
|---|---|---|
| module | イベントを発生させた保護領域です。 | まず同じ系統の FAQ 行を確認し、必要に応じて Build Integrity、Speed & Time Hack、Injection、Install Source、License など関連 manual セクションへ移動してください。 |
| subCode / checkName | 短い原因コードまたはチェック名です。 | 下の FAQ で同じ系統の症状を探すときに使います。たとえば platform_native は platform、emulator、signing、root、jailbreak 関連の設定を先に見るという意味です。 |
| reason / subReason | SDK が反応した理由を人が読める形でまとめた内容です。 | これは最終判断ではなくヒントです。まず module と subCode を確認し、その後で同じキーワードを含む下の症状行を探してください。 |
| platform / buildType | アプリが実行されたプラットフォームとビルド種類です。 | QA 用エミュレーターや development build の問題と、実際の release device の問題を分けて見てください。 |
よくある症状と最初の確認
| 症状 | 可能性が高い領域 | まず試すこと |
|---|---|---|
| OZero 適用後、アプリが起動直後に終了します。 | 起動中にセキュリティ応答が実行された可能性があります。 | Failure Diagnostics を有効にして一度再現し、module、subCode、reason を確認してください。failure log がない場合は ozero_abort.txt と Player log を確認し、Unity では Window > OZero Security > Check Setup も実行してください。 |
| Android エミュレーターでアプリが繰り返し終了します。 | Build Integrity または platform native check がエミュレーターを未対応ランタイムとして扱っている可能性があります。 | エミュレーター QA では blockEmulator (Android) または関連する platform check policy を緩和してください。ただし、リリースビルドでエミュレーターをブロックする方針なら、ストア配布前にポリシーを戻してください。 |
| ライセンス認証に失敗する、または任意の Pro サーバー機能を利用できません。 | ライセンスキー、アプリ識別情報、ネットワーク、サーバー署名キーの問題が考えられます。 | ライセンス問題の解決 で LICENSE_NOT_FOUND、ANDROID_BUNDLE_ID_MISMATCH、timeout、signature verification failure など実際のログを確認してください。 |
| Build Integrity または manifest 検証が失敗します。 | manifest がない、古い、未署名、または現在のビルドと一致していない可能性があります。 | Check Setup を実行し、integrity manifest を再生成し、signing key を検証してから clean build を作成してください。コード、IL2CPP 出力、watched file、manifest signing key が変わった後は再生成が必要です。 |
| 一時停止、スローモーション、早送り後にアプリが終了します。 | 直接 Time.timeScale を変更するコードが時間操作のように見える場合があります。 | OZeroTime.timeScale を使用してください。TimeScaleTamperExemptions は検証済み plugin または legacy adapter script に限定してください。 |
| 長いロード画面中にアプリが終了します。 | メインスレッドが非常に長くブロックされていました(Watchdog はブロックされたスレッドを待ちますが、5 分以上停止したプロセスは終了します)。 | 信頼できる長いロード区間だけ OZeroWatchdog.BeginLoadingGrace で囲んでください。通常のゲームプレイ停止を隠す目的で使わないでください。 |
| Android で Minify/ProGuard/R8 を有効にした後、アプリが終了します。 | Unity または custom Android bridge class が削除またはリネームされた可能性があります。 | Android ProGuard / R8 keep rules を適用してください。Unity bridge class と、プロジェクトが呼び出す Java/Kotlin bridge class を保持する必要があります。 |
| クリーンな Windows PC で Standalone ビルドがすぐ終了します。 | OZero native plugin または VC++ runtime を読み込めていない可能性があります。 | Microsoft Visual C++ Redistributable 2015-2022 (x64) をインストールし、OZero native plugin がビルド出力に含まれていることを確認してください。 |
| 正常な overlay や録画ツールで Injection イベントが出ます。 | Injection/Hooking がロード済みモジュールを観測している状況です。 | まず Failure Diagnostics か Pro ポータルで検知されたモジュール名、ハッシュ、署名者を確認してください。正規のプログラムなら、Pro のお客様はポータル(インジェクション → 検出モジュール)で該当行の許可を押すと、次回のリスト更新で全端末に反映されます。Standard のお客様はハッシュを injectionWhitelistEntries に入れて新しいビルドを配布します。名前を挙げられないモジュールは許可しないでください。 |
| optional Built-In TMP Dialog package の準備不足エラーでビルドが停止します。 | Built-In Managed Verification UI policy が選択されていますが、TextMeshPro、TMP Essential Resources、OZero dialog component、または既定 prefab が不足しています。 | Window > OZero Security > Check Setup を開き、Built-In TMP dialog エラーの Import Package を押してください。package import と script compilation の完了後に Check Setup を再実行し、もう一度ビルドしてください。ゲーム独自の UI を使う場合は Custom UI / Callback Only を選択します。 |
ビルド整合性検証器の設定
修正されたゲームファイル、デバッガーの接続、異常な実行環境を検知するビルド整合性チェッカーを構成します。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Build Integrity | checkbox | On | Dashboard の Build Integrity 有効化チェックボックスです。内部的には useIntegrity に対応します。 |
| validateOnStartup | bool | true | ゲーム実行直後にビルド整合性チェックを実行します。 |
| validateInEditor | bool | false | Unity エディターでも検証を実行します(テスト用には有用ですが、一般的な開発中はオフにすることを推奨)。 |
| enablePeriodicValidation | bool | true | ゲームの実行中にも無欠性の検証を繰り返します。開始時に1回の検証だけで十分なビルドでない場合はオンにしておくことをお勧めします。 |
| periodicCheckInterval | float | 300 s | ゲーム実行中に Build Integrity の再検証を繰り返す基準間隔(秒)です。0 以下にすると定期チェックを無効化します。 |
| periodicCheckJitterPercent | float | 35% | 検証の周期にランダムな変化を加えて、検査のタイミングを予測しにくくします。具体的な周期と範囲は公開された文書では案内せず、デフォルト値の使用をお勧めします。 |
| timingAnomalyConsecutiveRequired | int | 7 | タイミングに基づく異常な信号が何回累積されなければデバッガーのタイミングのドリフトとして判断するか決めます。強いデバッガーの信号は即座に失敗することがあります。 |
| timingAnomalyWindowSeconds | float | 900 s | タイミングに基づく異常な信号を累積する時間の窓です。長いほど寛大で、Strict はより短い窓を使用します。 |
| timingAnomalyFrameHitchSuppressionSeconds | float | 20 s | シーンのロード、シェーダーのコンパイル、GC、OS のスケジューリングの遅延のような大きなフレームのヒッチが発生した後、一定の時間の間タイミングに基づくデバッガーの検査を緩和します。 |
| checkAssemblyHash | bool | true | ビルド時に生成された manifest を基準に、コンパイル済みアセンブリのハッシュを検証します。 |
| checkDebugger | bool | true | デバッガー接続と、デバッガーのように見えるランタイムのタイミング異常を検知します。 |
| failOnDebugBuild | bool | false | Unity デバッグビルドを違反とみなします(リリースビルドで推奨)。 |
| checkPlatformNative | bool | true | プラットフォーム別のネイティブチェックを実行します。プラットフォームにより、root/jailbreak、APK 署名、実行環境、プロキシ、解析ツールのシグナルなどを確認します。 |
| failIfManifestMissing | bool | false* | Inspector のデフォルトは開発時の利便性のためオフです。ただし development ではないプレイヤービルドでは自動的にオンになり、oz_manifest.ozero が存在しない、または読み取れない場合は違反として処理します。 |
| failIfAssemblyHashBlobMissing | bool | false* | Inspector のデフォルトは開発時の利便性のためオフです。ただし development ではないプレイヤービルドでは自動的にオンになり、生成済みのアセンブリハッシュブロブを削除してもハッシュ検証を黙って回避できないようにします。 |
| requireCodeSignature (Windows) | bool | false | メイン実行ファイルがコード署名されている必要があります。Windows 専用。 |
| blockVirtualMachine (Windows) | bool | false | 仮想マシン内部でのゲーム実行をブロックします。Windows 専用。 |
| blockHyperV (Windows) | bool | false | Hyper-V VMBus の信号を遮断します。WSL2、Docker Desktop、Windows Sandbox のユーザーも防がれる可能性があるため、統制された環境でのみ慎重に使用してください。 |
| blockNetworkProxies (Windows) | bool | false | ネットワークプロキシ、パケット検査、トラフィック分析ツールと疑われる実行信号を検知します。対戦型のビルドで使用するものの、誤検知の可能性をテストしてください。 |
| blockReverseEngineeringTools (Windows) | bool | false | 逆アセンブルまたはデバッグツールと疑われる実行信号を検知します。開発/QA 環境とライブ環境を分離して検証してください。 |
| blockSystemMonitorTools (Windows) | bool | false | プロセス/システム監視ツールと疑われる実行信号を検知します。一般ユーザー環境での誤検知の可能性を考慮してください。 |
| il2cppHashGameAssembly | bool | true | Windows IL2CPP ビルドの GameAssembly.dll をハッシュ検証します。IL2CPP ファイルの保護の最小限の推奨項目です。 |
| il2cppHashGlobalGameManagers | bool | false | Windows IL2CPP ファイルハッシュ範囲に globalgamemanagers を追加します。コード上のデフォルトはオフですが、Standard と Strict プリセットではオンになります。 |
| il2cppHashSharedAssets | bool | false | Windows IL2CPP ファイルハッシュ範囲に sharedassets* ファイルを追加します。コード上のデフォルトはオフですが、Standard と Strict プリセットではオンになります。 |
| il2cppHashSceneFiles | bool | false | Windows IL2CPP ファイルハッシュ範囲に level* などの Unity シーンファイルを追加します。コード上のデフォルトはオフですが、Standard と Strict プリセットではオンになります。 |
| il2cppHashResourcesAssets | bool | false | IL2CPP 検証範囲に resources.assets を追加します。Strict モードに有用ですが、パッチの流れを先にテストしてください。 |
| il2cppAdditionalWatchedFiles | List<string> | — | プロジェクトに別途のネイティブペイロードが含まれる場合、追加で監視する Windows IL2CPP の出力ファイルを指定します。 |
| blockEmulator (Android) | bool | true | Android 専用です。エミュレーターまたは未サポートのランタイムシグナルを整合性違反として扱います。QA/エミュレーターテスト中には緩和し、プロダクションビルドではより厳格なポリシーを推奨します。 |
| blockSystemRwMount (Android) | bool | true | Android 専用です。システムパーティションが書き込み可能であったり root 系の mount 状態が見えれば整合性違反として処理します。Standard プリセットでは、アンロック済みまたは root 済み QA 端末での誤検知を減らすためにこの値を緩和します。 |
| linuxHostLayerPolicy (Linux) | enum | Monitor | LD_PRELOAD、LD_AUDIT、WINEDLLOVERRIDES のような Linux ホストレイヤーがゲームと OS の間にあるときの反応です。Off は無視、Monitor(Strict を含む全プリセットの既定)はゲームを終了せず記録のみ、Block は違反として扱います。正規の Steam Linux・Proton プレイヤーもこの層を使うため、Block はプレイヤー環境を検証したゲームだけで使ってください。 |
| protonPolicy (Linux / Proton) | enum | Monitor | Windows ビルドが Proton や Wine 上で動作しているときのポリシーで、値は上と同じです。既定の Monitor は Steam Deck・Proton プレイヤーのプレイを妨げず、環境をテレメトリーに記録します。 |
| acknowledgeHostLayerBlock | bool | false | Block のホストレイヤー・Proton ポリシーを使う前に有効にする必要がある確認スイッチです。この確認なしに Block を設定するとビルドの preflight が失敗するため、正規の Linux プレイヤーのゲームを誤って終了させるビルドは出荷されません。 |
| nativeModuleInventoryPolicy | Off | Monitor | Block | Block (Low: Monitor) | Windows・Linux プレイヤー専用です。ビルドがゲームフォルダー配下のすべてのネイティブモジュール(*.dll / *.so)を署名付き整合性マニフェストに記録します。起動時に Build Integrity がフォルダーを列挙し記録済みファイルをハッシュ化して、一覧にないネイティブファイルやハッシュが変わったファイルを違反とみなします。Block(既定)は終了、Monitorは記録して続行、Offは検査を省略します。Injection 検知器も同じ一覧でゲーム自身のプラグインを識別します。プレイヤーがゲームフォルダーにネイティブのモッドローダーを追加することを許可するなら Monitor を選んでください。Low プリセットは Monitor です。 |
| androidShaKeys | List<string> | — | 期待される APK 署名証明書の SHA-256 フィンガープリントリスト。インストールされた APK がこれらのキーのいずれかで署名されていない場合、検証に失敗します(Android 専用)。 |
| expectedBundleIds (iOS) | List<string> | — | 許可する iOS Bundle ID リストです。空いていれば Bundle ID の検査をパスします。 |
| excludedAssemblies | List<string> | — | ハッシュ検証から除外するアセンブリ名のリスト(.dll 拡張子を除く)。ランタイムに変更されるアセンブリ(例: 生成されたコード)に使用してください。 |
| checkIntegrityWithServer (Pro) | bool | false | Pro の nonce → attest フローを有効にします。ローカル Build Integrity が通過すると、SDK がビルド整合性の証拠を OZero に送信します。attestationVerificationMode=OZeroManaged、optional OZero TMP dialog package、内蔵 Managed Verification UI を使う場合、ユーザー向け検証フローのためのゲームコードは不要です。 |
| attestationVerificationMode (Pro) | enum | CustomerGameServer | OZA トークンの最終判定者を選択します。OZeroManaged では SDK が OZero に管理型セッション判定を問い合わせます。CustomerGameServer では自社サーバーが binding を発行し、クライアントが RequestGameServerAttestation(audience, challenge, sessionId) を呼び出した後、自社サーバーが OZero API で OZA トークンを検証します。 |
| attestationNetworkPolicy (Pro) | enum | RequireOnlineRevalidation | サーバー検証を完了または更新できない場合は、オンライン必須状態として処理します。OZeroManaged と内蔵 UI を使う場合、再試行、timeout、ブロック状態を SDK ダイアログで自動表示します。 |
| manifestSigningPublicKey | string | "" | 署名済み Build Integrity manifest を検証する Base64 RSA-2048 公開キーです。Window > OZero Security > Config & Dashboard の Generate Key Pair で生成してください。OZeroLicenseConfig に入力するカスタマーポータルのサーバーキーとは別のキーです。 |
| requireManifestSignature | bool | false* | Inspector のデフォルトは、キー生成前の開発用としてオフです。リリースプレイヤービルドでは manifest 署名検証が強制的にオンになるため、リリース前に必ずキーペアを生成してください。 |
| manifestSigningPrivateKeyPath | string | "" | ビルド時に manifest 署名に使用する private key PEM のパスです。空のままにすると [ProjectRoot]/OZeroSigningKeys/manifest_private_key.pem を使用します。Editor 専用であり、プレイヤービルドには含まれません。 |
既定 UI で使う OZero サーバー attestation
コードなしのフローでは、checkIntegrityWithServer を有効にし、attestationVerificationMode を OZeroManaged に設定し、optional OZero TMP dialog package を import してから General Settings の Managed Verification UI ポリシーを内蔵ダイアログのままにします。SDK が nonce の取得、attest 証拠の送信、OZero 管理セッション判定の取得を行い、ネットワーク必須、再試行、timeout、警告、ブロック状態を既定ダイアログで表示します。既定 UI を置き換える場合、TextMeshPro を使わない場合、または独自 telemetry/session gate を追加する場合は RegisterUserManagedVerificationStateCallback を登録してください。
💡 Tip: ライブビルドをより強いポリシーで保護するには
Pro Strict Attestation は、顧客ポータルの Pro ポリシーで有効にできる強化モードです。このモードでは、OZero サーバーは OZA トークンをすぐには発行せず、まずポータルに登録された有効なビルドからのリクエストかを確認します。提出された nonce、manifest hash、platform、SDK version、アプリ識別情報が同じリクエストの流れに属するかもあわせて検査します。さらに debugger、platform、speedhack、injection の検査結果が正常で、assembly/file/IL2CPP hash のいずれかが検証されている必要があります。条件を満たさない場合は OZA トークンが発行されないため、新しいビルドを配布する前に、顧客ポータルへビルドバージョンと manifest hash を登録してください。Events
| Event | Description |
|---|---|
| OnValidationPassed | ローカルの整合性チェックが違反なく完了したときに発生します。Pro サーバーの検証(attestation)はまだ進行中である可能性があります。 |
| OnAttestationPassed | Pro OZA 検証(attestation)トークンが実際に発行された後にのみ発生します。ゲームサーバーのログイン、PvP、ランキング、財貨の流れは、このイベントまたは AttestationToken.IsValid(nowMillis) で検査して通過した場合にのみ進行してください。 |
| OnValidationFailed | 整合性チェックが違反を検知したときに発生します。グローバルな onHackDetected イベントも ModulationType.BuildIntegrity と共にトリガーされます。 |
RSA 署名キーの生成(Build Integrity Manifest)
Build Integrity は、ビルド時に生成される manifest に RSA 署名を追加できます。この manifest には、ランタイムで検証する assembly hash とファイル整合性情報が含まれます。リリースビルドでは manifest 自体が差し替えられると検証基準を信頼できないため、配布前に Window > OZero Security > Config & Dashboard の Generate Key Pair で manifest 署名キーペアを生成してください。
ビルド時に、OZero は 秘密キーで manifest に署名します。プレイヤービルドには秘密キーは含まれず、OZeroSecurityConfig に保存された公開キーだけが含まれます。ランタイムでは、SDK がその公開キーで manifest の署名を確認します。署名が正しければ「ビルド時に作成された manifest がそのまま維持されている」と判断し、その manifest を基準に assembly/file hash 検査を行います。署名がない、または一致しない場合は manifest が差し替えられた、または編集された可能性があるため、Build Integrity 失敗として処理します。その後の動作は Response Settings に従い、ログ、コールバック、アプリ終了などになります。
キーペアを生成する
- Unity エディターで Window > OZero Security > Config & Dashboard を開きます。
- インスペクターで Build Integrity セクションを展開します。
- Require Manifest Signature チェックボックスを有効化します。
- Generate Key Pair ボタンをクリックします。
- OZero が Build Integrity manifest signing 用のキーペアを生成します。公開キーは
OZeroSecurityConfigに保存され、個人キー はデフォルトで次のパスに保存されます:[ProjectRoot]/OZeroSigningKeys/manifest_private_key.pem - 個人キーの位置を示す確認のダイアログボックスが表示されます。OK をクリックして閉じます。
- 個人キーファイルは Unity がビルドに含めないように
Assets/フォルダの 外部 に保存されます。絶対にAssets/の中に移動しないでください。 OZeroSigningKeys/はバージョン管理から除外してください。Git では.gitignore、SVN ではsvn:ignoreに追加します。個人キーをリポジトリへコミットすることは重大なセキュリティリスクです。- 個人キーは安全な場所にバックアップしてください。このファイルを持つ人は、そのプロジェクトの有効な Build Integrity manifest を作成できます。
- 個人キーを紛失した場合、既にリリース済みのビルドはそのまま動作します。ただし、次のアップデートビルドでは旧キーで新しい manifest に署名できません。新しいキーペアを生成し、integrity manifest を再生成して clean build で配布してください。公開キー、fingerprint、manifest、signature が一致していない場合、Build Integrity 検証に失敗することがあります。
ユーザー指定の個人キーのパス(CI/CD & チーム環境)
Manifest Signing Private Key Path は、Generate Key Pair が新しいキーを生成する場所を選ぶ設定ではありません。ビルドと検証ツールが読み込む PEM 秘密キーの場所を指定する設定です。Generate Key Pair はプロジェクトの既定パスにキーを作成し、そのパスを Config に記録します。CI/CD やチームビルドでは、同じ PEM を安全な場所に復元してから、このフィールドでそのパスを指定してください。
- CI/CD パイプライン — PEM を CI Secret に保存し、Unity ビルドの直前に復元します。ビルドランナーが秘密キーを常にディスクへ保持する必要はありません。
- チーム環境 — リリースビルド担当者やビルドランナーだけがアクセスできるセキュアなマウントパス、またはシークレットマネージャーを使用します。すべてのリリースビルドマシンは同じ PEM を使用する必要があります。
既存のキーペアの検証
ディスク上の秘密キーと OZeroSecurityConfig に保存された公開キーが一致しているか確認するには、Validate Key Pair をクリックしてください。OZero は PEM から公開キーを再計算し、Config の公開キーと比較します。一致しない場合は、対応する秘密キーを復元するか新しいキーペアを生成し、その後 clean build を作成してください。
- 個人キーを紛失または流出した場合。
- Validate Key Pair で不一致を報告する場合(キーが同期されていない場合)。
- 予定されたセキュリティポリシーの一環として意図的にキーを交換する場合。
再生成後も、既にリリース済みのビルドは自分のビルドに含まれるキーと manifest でそのまま動作します。次のアップデートビルドでは、新しい公開キー、fingerprint、manifest、signature が1つのセットとして一致している必要があります。integrity manifest を再生成し、clean build で配布してください。
デュアルフィンガープリントのキー回転
Generate Key Pair ボタンを押すと、公開キーが OZeroSecurityConfig に保存され、同じキーを識別する fingerprint が Assets/OZeroSDK/Scripts/Security/BuildIntegrity/OZeroManifestTrustAnchor.cs にも記録されます。ランタイムでは、まず asset 内の公開キーが信頼済み fingerprint と一致するか確認してから、署名済み manifest を受け入れます。
ExpectedPublicKeyFingerprintHex は現在のビルドで使うキーの fingerprint です。PreviousPublicKeyFingerprintHex はキー回転期間だけ使う補助スロットです。この機能は manifest の再生成を置き換えるものではなく、サーバー側のキー管理機能でもありません。OZeroSecurityConfig の公開キー、fingerprint、manifest、signature は、同じキーを基準に1つのセットとして一致している必要があります。
安全なキー回転手順
- 現在の fingerprint をバックアップします。
Assets/OZeroSDK/Scripts/Security/BuildIntegrity/OZeroManifestTrustAnchor.csを開き、ExpectedPublicKeyFingerprintHexの値を一時メモにコピーします。 - 以前のキースロットに登録します。 同じファイルの
PreviousPublicKeyFingerprintHexに1段階でコピーした値を貼り付けて保存します。 - 新しいキーペアを生成します。 Window > OZero Security > Config & Dashboard を開き、Build Integrity セクションで Generate Key Pair をクリックします。新しい公開キーと Expected fingerprint が自動的に更新されます。2番目の手順で入れた Previous の値は維持してください。
- integrity manifest を再生成し、clean build を作成します。 新しい manifest と signature は、新しい秘密キーを基準に生成される必要があります。
- アップデート移行期間を設けます。 既存リリースビルドは、自分のビルドに含まれるキーと manifest で引き続き動作します。Previous スロットは、新しいビルドの配布中にロールバックや成果物の混在が起きた場合の安全策です。ライブゲームでは通常 1〜4 週間程度を目安にします。
- 以前のキースロットを空にします。 古いビルドの使用量が十分に低くなった後、
PreviousPublicKeyFingerprintHex = ""に戻し、もう一度リリースすると回転が完了します。
既にリリースされた旧ビルドは、新しいキーを知らなくても動作し続けます。旧ビルドには当時の公開キー、fingerprint、manifest、signature が一緒に含まれているためです。Previous スロットは、新しいリリースラインで管理されたキー回転期間だけ使う安全策です。移行期間が終わったら、後続リリースで空にしておくことを推奨します。
トラブルシュート
問題が起きたら、まず簡単な順序で確認してください。キーがない場合は Generate Key Pair を実行し、キーがある場合は Validate Key Pair を実行します。その後、integrity manifest を再生成して clean build を作成します。ほとんどの問題は、秘密キー PEM、OZeroSecurityConfig の公開キー、OZeroManifestTrustAnchor の fingerprint、生成済みの manifest/signature ファイルのどれかが一致していないときに発生します。
ExpectedPublicKeyFingerprintHex が空である可能性があります。リリースビルドは fingerprint がない場合、安全のためすぐ失敗します。解決: Generate Key Pair を実行し、Unity の再コンパイルが終わったあと clean build を作成してください。値がすでに入っている場合は Validate Key Pair を実行し、ビルド出力フォルダーを空にしてから再ビルドしてください。
OZeroSecurityConfig.Integrity.ManifestSigningPublicKey が空のときに発生します。解決: Window > OZero Security > Config & Dashboard を開き、Build Integrity セクションの Generate Key Pair をクリックしてから再度ビルドしてください。
OZeroSecurityConfig の公開キーと OZeroManifestTrustAnchor に記録された fingerprint が一致しないときに発生します。キーペアの一部だけを復元した場合や、生成されたファイルを手動で編集した場合によく発生します。解決: Validate Key Pair を実行してください。不一致が報告された場合は、対応する PEM を復元するか新しいキーペアを生成し、integrity manifest を再生成して clean build を作成してください。配布済みビルドでのみこのメッセージが表示される場合は、APK または実行ファイルが再パッケージされていないかも確認してください。
回転したキーセットの一部が古い値のままになっている可能性があります。公開キー、fingerprint、manifest、signature が同じキーを基準に一致しているか確認してください。解決: 移行期間が必要な場合だけ以前の fingerprint を PreviousPublicKeyFingerprintHex に維持し、Validate Key Pair 実行、integrity manifest 再生成、ビルド出力フォルダーの整理、clean build の順に再ビルドしてください。
CI にはローカル PC の OZeroSigningKeys/manifest_private_key.pem が自動では存在しません。解決: PEM を CI Secret に保管し、Unity ビルドの直前に既定パス、または Manifest Signing Private Key Path に指定したパスへ復元してください。すべてのリリースランナーが同じ PEM を使用する必要があり、リリース環境でも一度 Validate Key Pair を実行して確認することを推奨します。
インストール元の設定
ゲームが承認されたストアまたは経路からインストールされた場合にのみ実行されるように制限します。サイドロードや再パッケージされた APK の防止に役立ちます。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Install Source | bool | true | Install Source モジュールを有効化します。 |
| allowGooglePlayStore | bool | true | Google Play ストア経由のインストールを許可します。 |
| allowSamsungGalaxyStore | bool | false | Samsung Galaxy Store 経由のインストールを許可します。 |
| allowAmazonAppstore | bool | false | Amazon Appstore 経由のインストールを許可します。 |
| allowHuaweiAppGallery | bool | false | Huawei AppGallery 経由のインストールを許可します。 |
| allowOneStore | bool | false | ONE Store(韓国)経由のインストールを許可します。 |
| allowXiaomiGetApps | bool | false | Xiaomi GetApps 経由のインストールを許可します。 |
| allowOppoAppMarket | bool | false | OPPO App Market 経由のインストールを許可します。 |
| allowVivoAppStore | bool | false | Vivo App Store 経由のインストールを許可します。 |
| allowADB | bool | false | ADB(Android Debug Bridge)経由のインストールを許可します。内部テスト目的でのみ有効化してください。 |
| allowDetectionFailed | bool | false | Android の installer package 照会そのものが失敗した場合でも起動を許可します。ADB のように空の値が返る状況とは別で、JNI 呼び出しやプラットフォーム API が最後まで実行できなかった場合です。リリースビルドでは通常オフにします。 |
| allowUnknownSources | bool | false | 標準ストア一覧にも customAuthorizedPackages にもない installer package を許可します。地域ストア配布が必要な場合だけ、実機で確認してから使ってください。 |
| enableServerSync (Pro) | bool | false | Pro 専用です。ローカル検出後に /v1/install-source/verify へ installer package を送り、サーバー側 allowlist と監査ログを適用します。サーバーにまだルールがない場合は opt-in 動作として許可されます。 |
| customAuthorizedPackages | List<string> | — | 追加で許可するインストーラーのパッケージ名(例: com.yourcompany.launcher)。 |
| reportViolationToCallback | bool | true | 許可されていないインストール元が検知された場合、サーバーにレポートを送信します。 |
| logRawInstallerPackage | bool | true | 検出された元の installer package name をログに出します。カスタムストアのパッケージ名を探す QA 段階では便利ですが、リリースログに出してよい情報か確認してから残してください。 |
Steam Anti-Piracy の設定
Steam に配布される PC ビルドで Steam の実行の経路、App ID、権限の状態、リリースの設定を確認します。Standard はローカルの検証であり、Steam サーバーを通じたより強い所有権の検証は Pro のサーバー Steam Attestation で提供します。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Steam Anti-Piracy | checkbox | Off | Steam Anti-Piracy の活性化のチェックボックスです。Steam App ID と配布の方式がプロジェクトごとに異なるためデフォルト値は Off です。まず観察/QA モードで状態を確認した後、リリースビルドのポリシーを強化してください。 |
| expectedSteamAppId | int | 0 | プロジェクトの Steam App ID です。開発の確認用 AppID 480 を使用した場合、リリースの前に必ず実際の App ID に変えてください。 |
| requireSteamLaunch | bool | true | ゲームが実行ファイルの直接実行ではなく Steam を通じて開始されたか確認します。開発中の直接実行のテストとリリースポリシーを区分してください。 |
| requireSteamApiInit | bool | true | Steam API の初期化の成功可否を確認します。ローカルの開発の実行では Steamworks の設定によって失敗することがあるため、最終的な判定は実際の Steam 配布の経路で確認してください。 |
| requireSubscribedCurrentApp | bool | true | 現在の Steam アカウントがアプリを所有するか使用の権限を持っているか確認します。この項目はローカルの検証であり、サーバー側の所有権の検証は Pro で実行します。 |
| requiredDlcAppIds | List<int> | — | 所有確認を行う Steam DLC App ID のリストです。有料 DLC や必須 DLC がある場合は、その App ID を追加してください。 |
| blockSteamAppIdTxtInRelease | bool | true | steam_appid.txt は、Steam を使わずにローカル起動テストを行うための開発用ファイルです。リリースビルドに残っていると Steam 経由でない起動を許してしまう可能性があるため、OZero は違反として扱います。配布前にプロジェクトルートとビルド出力物から削除してください。 |
| validateSteamApiDllHash | bool | false | Steam API DLL のハッシュを既知の SHA-256 値と比較して検証します。 |
| allowFamilySharing / allowFreeWeekend / allowTimedTrial | bool | true | Steam の家族の共有、無料の週末、時間制限の体験の権限の状態を許可するか制御します。 |
| requireSteamBuildIdNonZero | bool | false | Steam が Build ID を 0 として返す、または Build ID を取得できない場合に違反として扱います。Steam depot/build の配布フローで Build ID が正しく取得できることを確認してから有効にしてください。 |
| expectedSteamApiDllSha256Hashes | List<string> | — | validateSteamApiDllHash を有効にしたときに比較する Steam API ファイルの許可 SHA-256 一覧です。配布する Steamworks SDK バージョン、プラットフォーム、リリースブランチごとにハッシュを登録してください。 |
| requireValveSignedSteamApi | bool | true | Steam API 再配布ファイルが Valve のプラットフォーム identity と一致することを要求します。Windows では Authenticode 署名者を検証し、macOS では Valve Team ID を検証します。その他のプラットフォームでは SHA-256 検証を fallback identity check として使用してください。 |
| detectKnownSteamEmulators | bool | true | 実行ファイルの周辺で、Goldberg、CreamAPI、SmartSteamEmu、ColdClientLoader などの Steam エミュレーターが残しやすいファイルやフォルダーを探します。見つかった場合は、通常の Steam 起動ではない可能性があるものとして扱います。 |
| requireSteamEnvironmentConsistency | bool | true | リリースビルドで、Steam が有効な個人 SteamID と 0 以外の Build ID を返しているか確認します。Steam クライアント/ライブラリパスの事前確認は警告ログに残し、SteamID または Build ID が不正な場合は違反として扱います。 |
| observeSteamAuthTicketHeuristic | bool | true | ローカル Steam 認証チケットのサイズと基本的な形式だけを参考信号として確認します。チケットの内容はログに残さず、この検査だけでゲームをブロックすることもありません。 |
| detectionAction | OZeroSteamDetectionAction | Callback | Steam 検証に失敗したとき、SDK がローカルでどこまで処理するかを決めます。Observe はログと診断だけを残し、Callback はゲーム側コールバックを呼び出し、Block は違反をブロックポリシーとして扱います。実際にアプリを終了するかは Global Threat Response 設定に従います。 |
| reportViolationToCallback | bool | true | Callback モードで Steam 検証に失敗したとき、通常の OZero セキュリティコールバックへ渡すかを決めます。ログだけ確認し、ゲーム側コールバックを止めたい QA ビルドでのみ無効にしてください。 |
| forceSteamAntiPiracyObserveOnly | bool | false | Steam 検証失敗を一時的にログと診断記録だけに留める観察モードで扱います。特殊な Steam 起動環境をテストするときだけ使用し、リリース前には必ず無効にしてください。 |
| checkSteamDrmWithServer (Pro) | bool | false | Pro 専用です。サーバー根拠を使った Steam DRM 検証を有効にします。ローカル Steamworks 状態だけでなく、Steam 所有権をサーバー側の証拠で確認したい場合に使用します。 |
| steamDrmVerificationMode (Pro) | OZeroSteamDrmVerificationMode | OZero Managed | Steam DRM 検証の担当を選択します。OZeroManaged では SDK が OZero /v1/steam/attest を直接呼び出し、activation cache を管理し、optional OZero TMP dialog package を import した後にユーザー向け状態を既定の Managed Verification UI に渡します。CustomerGameServer は、自社サーバーが OZA token と Steam ticket を受け取り、OZero server API を呼び出す構成です。 |
| steamDrmNetworkPolicy (Pro) | OZeroSteamDrmNetworkPolicy | RequireOnlineRevalidation | 最新のサーバー再検証が必要な時点でネットワークまたはサーバーを利用できない場合は、オンライン必須状態として処理します。OZeroManaged と import 済みの内蔵 UI package を使う場合、再試行フローを自動表示します。 |
OZeroManaged を使う場合、保護対象の初回起動は OZero サーバー経由で有効な activation token をオンライン取得します。その後は、有効な cache token とオフライン猶予が残っていればオフライン実行を許可できます。トークン期限切れ、猶予終了、または再検証が必要な時点でユーザーがオフラインの場合、OZeroSecurity_BuiltInDialog_TMP.unitypackage を import した既定の Managed Verification UI がオンライン必須通知、Retry ボタン、retry timeout、ブロック状態を自動処理します。
OZero サーバー管理の Steam DRM
checkSteamDrmWithServer を有効にし、steamDrmVerificationMode を OZeroManaged に設定し、OZeroSecurity_BuiltInDialog_TMP.unitypackage を import してから General Settings の Managed Verification UI ポリシーは内蔵ダイアログのままにします。SDK が Steam auth ticket を OZero サーバーへ送信し、activation token cache を管理し、オンライン必須、再試行、timeout、警告、ブロック状態を既定 UI で表示します。内蔵 UI をそのまま使う場合、callback や retry コードは不要です。
顧客ゲームサーバーでの Steam 検証
checkSteamDrmWithServer を有効にして CustomerGameServer を使用します。自社サーバーが audience、256-bit hex challenge、session ID を発行し、ローカル検証後にクライアントが RequestGameServerAttestation(...) を呼び出して callback の OZA token、同じ binding 値、Steam Auth Ticket を送信します。サーバーは /v1/validate と /v1/steam/attest を呼び出し、両方の server API key はサーバー側だけに保管します。
デバイスバインディング設定
最初に信頼した端末の識別情報を保存し、以降の起動時に同じ端末かどうかを比較します。同じアカウントや保護されたセーブデータが別の端末へ移されたかを確認するために使います。
運用での使い方
Pro では Device Binding を運用ツールとして使えます。サーバーがライセンスごとの端末フィンガープリントを記録するため、繰り返しリスクが出る端末をブロックし、安易なライセンス共有を減らし、正当な端末変更はライセンス全体を止めずにサポートできます。
繰り返しリスクが出る端末をブロック
SpeedHack、Injection、Install Source、Build Integrity などのセキュリティイベントを確認した後に使用してください。ブロックされた端末は、次回の有効化、端末登録、端末検証、ポリシー確認で DEVICE_BLOCKED を受け取ります。
正当な端末変更をサポート
実際のプレイヤーが端末を買い替えた、OS を再インストールした、ハードウェアを交換した、または通常の環境変化で端末情報が変わった場合に Reset Token を使います。トークンは 5 分間のみ有効で 1 回だけ使用でき、正確なライセンスと端末に紐づきます。
登録可能な端末数を制限
Pro ライセンスでは maxDevices により、1 つのライセンスに登録できる有効な端末フィンガープリント数を制限します。ブロックされた端末が自動的に安全な空き枠になるわけではないため、リセットや削除はサポート確認後に行ってください。
Reset Token サポート手順
- 端末リセットが必要な理由とプレイヤーアカウントを、通常のサポート手順で先に確認します。
- Customer Portal → Device Binding で対象端末を選び、Reset Token を発行します。
- トークンは認証済みのサポートチャネルでのみ渡してください。公開チャット、スクリーンショット、長く残るチケットに残さないでください。
- ゲームまたはサポート用 UI から、トークンを
OZeroDeviceBindingDetector.Instance?.ClearStoredFingerprint(token.Trim())に渡します。 - SDK がトークンを受け入れた後、アプリを再起動するか保護初期化フローをもう一度実行すると、現在の端末フィンガープリントが再登録されます。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Device Binding | bool | true | Device Binding 検査を有効にします。有効にすると、SDK は起動時にローカル端末フィンガープリントを作成し、保存済みの値と比較します。 |
| hardwareChangeTolerance | int (0–3) | 1 | 端末フィンガープリントを構成する項目がいくつ変わっても同じ端末とみなすかを決めます。0 は厳格、3 は大きなハードウェア/OS 変更にも広く対応します。既定値 1 は小さな OS またはファームウェア変更を吸収するための値です。 |
| storageKey | string | "ozero_dfp" | SDK が暗号化されたローカル端末フィンガープリントを保存するときに使う PlayerPrefs キーです。ゲーム側で同じキーをすでに使っている場合だけ変更してください。 |
| enableServerSync (Pro) | bool | false | Pro 専用です。初回使用時に /v1/device/register で端末フィンガープリントを登録し、以降の起動では /v1/device/verify でサーバー記録と比較します。ネットワークやサーバー障害だけではゲームを止めませんが、サーバーが DEVICE_BLOCKED、FINGERPRINT_MISMATCH、DEVICE_LIMIT_REACHED のような明確な拒否を返した場合は Device Binding 違反として扱います。 |
| maxDevices (Pro) | int | 0 | 1 つのライセンスに登録できる端末数を示す参考値です。0 は制限なしを意味します。実際の上限はサーバーのライセンス記録または Customer Portal のポリシーで適用されるため、クライアントでこの値だけを変えても本番の上限は増えません。 |
Speed & Time Hack 設定
Unity 時刻、ネイティブ基準時計、バックグラウンドタイマー、Web/Pro サーバー時刻を比較し、ゲーム速度を速く/遅くする操作や端末時計の変更を検出します。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Speed & Time Hack | bool | true | Speed & Time Hack 検査を有効にします。有効にすると、SDK は実行中の時刻進行比率と端末時計の変更を監視します。 |
| autoStart | bool | true | ゲーム実行時に自動的に検出を開始します。無効にする場合は、OZeroSpeedHackDetector.StartDetection() で手動で開始する必要があります。 |
| checkInterval | float | 1.0 s | Unity 時刻と基準タイマーを比較する周期です。短くすると反応は速くなりますが、CPU 負荷と誤検知の可能性が上がります。 |
| requiredDetections | int | 3 | 違反として扱う前に、異常シグナルが連続で何回必要かを決めます。不安定な端末で誤検知を減らしたい場合は値を上げてください。 |
| ratioTolerance | float | 0.15 | Unity 時刻とネイティブ基準時刻の差を、この比率までは正常として扱います。まず既定値で始め、実プレイで誤検知が出る場合だけ調整してください。 |
| maxAllowedRatio | float | 4.0 | 時刻進行比率がこの値を超えると、強いスピードハックシグナルとして扱います。通常のゲームでは既定値を維持してください。 |
| detectSlowHack | bool | false | 時間を速くする操作だけでなく、遅くする操作も検出します。既定値は false です。スローモーション、カットシーン、意図した速度変更を実際に確認してから有効にしてください。 |
| enableTimeScaleDetection | bool | true | Time.timeScale が未承認のコードやメモリ編集で変更されたかを確認します。意図的な速度変更には OZeroTime.timeScale を使ってください。 |
| hackDetectMultiplier | float | 1.3 | 時刻進行が maxAllowedRatio より大きく跳ねたとき、より強い疑いシグナルとして数える基準です。通常は既定値を維持してください。 |
| enableThreadTimerCheck | bool | true | バックグラウンドスレッドタイマーを追加の基準時計として使います。メインスレッドだけを操作するツールの検出に役立ちます。 |
| useWebTimeValidation | bool | true | HTTPS 時刻応答の Date ヘッダーまたは Pro サーバー時刻で端末時計の操作をクロスチェックします。既定値は true です。 |
| webSyncInterval | float | 15 s | Web/サーバー時刻と再比較する周期です。短くしすぎるとネットワーク要求が増えます。 |
| webRatioTolerance | float | 0.15 | 端末時刻と Web/サーバー時刻の差を、この比率までは正常として扱います。地域ごとのネットワーク遅延を考慮して実機で確認してください。 |
| timeOffsetTolerance | float | 60 s | 端末時計と Web/サーバー時刻の絶対差がこの秒数を超えると、時刻操作として扱います。 |
| focusIgnoreTime | float | 4 s | アプリがフォーカスを取り戻した直後に無視する時間(秒)。OS がアプリを一時停止したときに発生する誤検知を防ぎます。 |
| loadingGraceTime | float | 6 s | アプリ起動やシーン読み込みの直後、この時間は検出結果を無視します。重いロード区間での誤検知を減らします。 |
| lagSpikeIgnore | float | 0.5 s | フレーム時間がこの値を超えたサンプルは遅延として破棄します。実際のラグを時刻操作と誤認しないための設定です。 |
| buildFailIfTimeScaleTampered | bool | true | 保護対象コードが承認済みポリシー外で Time.timeScale を直接変更しているように見える場合、ビルド/検証段階で失敗させます。 |
| timeScaleTamperExemptions | List<string> | — | Time.timeScale を直接変更してよいスクリプト/メソッド名パターンです。一時停止、バレットタイム、カットシーンなど、確認済みのコードだけを最小限登録してください。 |
| webTimeUrls | string[] | — | Web/サーバー時刻確認に使う HTTPS アドレス一覧です。1 つのアドレスが遮断されても検査が止まらないよう、自分で管理する、または信頼できるアドレスを 2 つ以上入れることを推奨します。 |
| minSuccessfulEndpoints | int | 2 | 1 回の検査で、最低いくつのアドレスが有効な Date ヘッダーを返せば時刻を信頼するかを決めます。登録したアドレス数より大きい値にしないでください。 |
| maxConsecutiveFailures | int | 6 | Web/サーバー時刻確認がこの回数だけ連続で失敗すると、onWebTimeUnavailable ポリシーを実行します。一時的なネットワーク障害をすぐ違反にしないための余裕値です。 |
| onWebTimeUnavailable | WebTimeUnavailablePolicy | WarnOnly | Web/サーバー時刻を何度も確認できない場合の処理を決めます。WarnOnly は警告だけ残して継続します。Strict は繰り返し失敗を疑わしい状況として扱い、SpeedHack コールバックを発生させます。Silent はログも残さないため、特殊テスト以外では使わないでください。 |
| detectTimeHack | bool | true | 端末時計の変更と Web/サーバー時刻との差を検査します。速度比率検査とは別に、システム時刻操作を検出するオプションです。 |
| webSyncJitterPercent | float | 20% | Web/サーバー時刻確認がすべての端末で同時に重ならないよう、設定した周期の前後に呼び出し時刻を少し分散します。例: 20% なら 15 秒周期はおよそ 12〜18 秒の間で実行されます。 |
| sustainedLagThreshold | float | 0.15 | 直近フレーム平均がこの値より遅い場合、SDK はまず実際のラグとして扱い、その間の時刻検査結果をすぐ違反確定にはしません。既定の 0.15 秒は平均約 6〜7 FPS です。 |
| sustainedLagGraceDuration | float | 3 s | ラグと判断した後、厳密な時刻判定を一時的に保留する時間です。ラグが続く間はこの保留時間が延長され、ランタイムでは最大 10 秒までに制限されます。 |
| overloadStrictMultiplier | int | 3 | onWebTimeUnavailable が Strict のとき、失敗が明確なサーバー拒否ではなく単なるタイムアウトに見える場合、何回分多く待つかを決める倍率です。既定の 3 は maxConsecutiveFailures の 3 倍まで待ってからコールバックを発生させるという意味です。 |
| enableRemoteSpeedHackConfig (Pro) | bool | false | Pro サーバーポリシーで一部の Speed & Time Hack 基準値をアプリ更新なしで調整します。サーバーに接続できない場合はローカル Inspector 値で動作し続けるため、保護がオフになることはありません。 |
| remoteSpeedHackConfigInterval | float | 300 s | Pro サーバーから Speed & Time Hack のリモート設定を再取得する周期です。0 はアプリ起動時に 1 回だけ取得し、正の値では定期的に新しいポリシーを確認します。 |
| remoteSpeedHackConfigJitterPercent | float | 20% | Pro リモート設定を多くの端末が同時に要求しないよう、設定更新の時刻を少し分散します。 |
| enableSignedServerTime (Pro) | bool | false | Pro アクティベーションが使えるとき、署名付き /v1/time 応答を優先信頼時刻として使います。サーバーキーと時刻エンドポイントを設定し、テストしてから有効にしてください。 |
Time.timeScale ではなく OZeroTime.timeScale を使用する
Speed & Time Hack 保護モジュールが有効な状態では、プロジェクトコードから Unity 標準の Time.timeScale を直接変更しないでください。OZero を経由せず直接変更すると、OZero detector は外部チートツールによる疑わしいランタイム時間操作として扱い、設定された応答ポリシーを実行する可能性があります。
OZeroSecurityConfig.TimeScaleTamperExemptions は、直接 Time.timeScale へアクセスする必要があるスクリプトを登録する例外リストです。このリストは最小限にしてください。
構造上、直接 Time.timeScale にアクセスせざるを得ない検証済みの外部プラグインや legacy adapter script にのみ限定して割り当ててください。
それ以外のすべてのゲームロジックでは、例外なく OZeroTime.timeScale を優先してください。一時停止、スローモーション、カットシーン速度制御、倍速再生など、ゲーム内で意図的に速度を変更する場合は必ず OZeroTime.timeScale を使用してください。
using OZeroSDK.Security;
// Correct: the detector knows this is an intentional game-side change.
OZeroTime.timeScale = 0.5f;
// Avoid: this bypasses OZero's expected time-scale tracking.
Time.timeScale = 0.5f;
OZeroTime.timeScale に置き換えてください。
長時間ロード中の意図しない Watchdog 終了を防ぐ
OZero のネイティブ Watchdog は、Unity のメインスレッドが動き続けているかを定期的な heartbeat で確認します。リリースビルドの heartbeat 期限はすべてのプラットフォームで約 10 秒です(起動時の猶予の後)。期限を超えると Watchdog はまずメインスレッドが何をしているかを見ます。スレッドがブロックされ CPU を使っていない状態(長い同期ロード、ログのフラッシュ、ディスク I/O、仮想マシンによる一時停止)はストールとして記録のみ行い、ゲームが動き続けているのに heartbeat だけが来ない場合は改ざんとみなして設定された対応ポリシーに従って終了します。5 分以上停止したプロセスは応答なしとして終了します。
大きなシーンのロード、同期的なアセット解凍、シェーダー warmup、Addressables の準備など、メインスレッドを数秒以上意図的にブロックする正当な処理でも、この状況は発生する可能性があります。
このような信頼できるロード境界は OZeroWatchdog.BeginLoadingGrace(maxGraceMs) で囲んでください。ロード開始時に grace が始まり、scope が dispose されるか End() が呼ばれた瞬間に終了するため、正確なロード時間を事前に知る必要はありません。
using OZeroSDK.Security;
using UnityEngine.SceneManagement;
public void LoadLargeScene()
{
using (OZeroWatchdog.BeginLoadingGrace(60000))
{
SceneManager.LoadScene("Battle", LoadSceneMode.Single);
// Grace ends as soon as the using scope exits.
}
}
public void WarmUpLargeAssets()
{
OZeroWatchdog.RunWithLoadingGrace(() =>
{
BuildLargeRuntimeCache();
}, 60000);
}
この機能は、長いロード処理中にアプリがシステムによって強制終了されるのを防ぐための一時的な猶予です。セキュリティ回避やアプリを常時動かし続ける目的には使用できません。
許容時間を超える重いロード処理がある場合は、処理を小さな単位に分けるか、Unity の Coroutine / async ロードを使って画面とメインスレッドが止まったままにならないようにしてください。
物理ハック検出器
OZeroSecurityConfig.PhysicsHack は全体のオン/オフと Pro telemetry だけを制御します。速度制限、距離許容値、壁抜け検査、加速度検査は、それぞれの OZeroPhysicsHackDetector コンポーネントで設定します。プレイヤープレハブに追加し、キャラクターや車両の実際の移動ルールに合わせて値を調整したうえで、スポーン後に Initialize(playerId) を呼び出してください。| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| physicsHack.useGlobalPhysicsHack | bool | true | すべての Physics Hack コンポーネントをまとめてオン/オフするスイッチです。物理移動チェックを意図的にすべて止めたい場合だけオフにしてください。 |
| physicsHack.enableServerTelemetry (Pro) | bool | false | Pro 専用で、既定では無効です。プロジェクトが明示的に同意した場合のみ、一般セキュリティイベントと詳細な PhysicsHack telemetry を送信します。無効化すると新しい telemetry 送信を停止し、サーバーポリシーはローカル同意なしに送信を有効化できず、無効化のみ行えます。 |
| physicsHack.telemetryThrottlePerMinute (Pro) | int | 30 | このクライアントが 1 分間に送信できる PhysicsHack telemetry 数を制限します。基準値の設定ミスでサーバーへイベントが大量送信されることを防ぎます。 |
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| maxAllowedSpeed | float | 15 u/s | このオブジェクトが通常到達できる最大移動速度です(Unity units/second)。キャラクターや車両がゲーム内で正当に出せる最速値に合わせて設定してください。 |
| distanceTolerance | float | 2.0 u | maxAllowedSpeed から計算した移動可能距離に追加して許可する距離です。ネットワーク位置補正、物理計算の丸め、コントローラーの小さな揺れを吸収するために使います。 |
| obstacleLayer | LayerMask | — | 壁や固い障害物として扱うレイヤーです。OZero は前回の安全な位置から現在位置までの経路を調べ、途中でこのレイヤーに当たると壁抜けとして扱えます。 |
| checkInterval | float | 0.05 s | このコンポーネントが位置、壁抜け、加速度異常を確認する周期です。値を下げると反応は速くなりますが、CPU 使用量が増える場合があります。 |
| maxDeltaTimeCap | float | 0.1 s | 距離計算に使うフレーム時間の最大値です。長い 1 フレームだけで許可移動距離が大きくなりすぎることを防ぎます。 |
| violationThreshold | int | 2 | コールバックを発生させる前に、異常チェックが何回続く必要があるかを指定します。正常チェックが出るとカウンターが下がるため、小さな物理の揺れ 1 回だけでは違反になりません。 |
| castRadius | float | 0 | 壁抜け検査に使う半径です。0 の場合は CharacterController または CapsuleCollider から自動推定し、見つからなければ線の検査に切り替わります。 |
| enableAccelerationCheck | bool | true | Rigidbody の速度が急に大きく変わっていないかを確認します。kinematic オブジェクト、サーバー権威の移動、カスタム移動など、物理以外の方法で速度が変わることが正常な場合は、オフにすることを検討してください。 |
| maxAllowedAcceleration | float | 60 | 検査の間に許可する最大速度変化量です。ダッシュ、ノックバック、ジャンプ台、車両など、瞬間的に大きく加速する正常移動がある場合は、その動きに合わせて上げてください。 |
| enableLog | bool | true | 調整中にこのコンポーネントのデバッグログを表示します。ただし obstacle layer が空など重要な設定ミスは、この値がオフでも警告されます。 |
Injection Detector 設定
実行中のゲーム内部に入り込むプログラムを検知します。注入されたネイティブモジュール、実行可能なプライベートメモリ、インラインフック、リモートスレッド型の注入、高リスクのプロセスハンドル、WebGL ランタイム改ざんが対象です。正規のオーバーレイやキャプチャツールも同じ経路でゲームに入るため、検知器はすべてのモジュールをファイルハッシュと署名者で識別し、モジュールごとに判断できるようにします。
正規のオーバーレイ、録画ソフト、パートナー SDK、自分のゲームに同梱したモジュールが検知された場合だけ許可してください。先に Failure Diagnostics か Pro ポータルでモジュール名、ファイルハッシュ、署名者を確認してください。よく見かけるという理由だけで許可しないでください。チートツールもありふれています。
| フィールド | Type | デフォルト | 説明 |
|---|---|---|---|
| Activate Injection & Hooking | checkbox | On | Config Dashboard の Injection & Hooking オン/オフ項目です。内部的には useInjection に対応します。プレイヤービルドではネイティブ Injection 検査を実行し、開発ビルドでは原因確認のために緩やかな診断フローで動作し、エディターでは通常検査しません。 |
| injectionWhitelistEntries | OZeroInjectionWhitelistEntry[] | empty | すべてのティアで使えるローカル信頼モジュールリストです。各項目は、モジュールファイルの SHA-256 hash と任意の signer fingerprint で特定のファイル 1 つを許可します。ゲームと一緒に配布する、または QA、診断ファイル、Pro telemetry、OZero サポート案内で確認したモジュールだけ登録してください。 |
| enableServerWhitelist (Pro) | bool | false | Pro 専用。ポータルでの許可/ブロック判定と OZero のグローバル判定から作られた署名付きリストをダウンロードし、SDK ベースラインとローカルリストに統合します。許可されたモジュールはサイレント、ブロックされたモジュールは即時終了です。検証済みリストはオフライン起動用にキャッシュされ、サーバーに届かなくても最後のリストで保護が続きます。 |
| serverWhitelistRefreshInterval | float | 0 s | 実行中のゲームが Pro の判定リストを再ダウンロードする間隔です。0 なら起動時に一度だけ取得します。短いほどポータルの判定が早く届きますが通信量が少し増え、次回起動時にも更新されます。 |
| requireSignerForNativeWhitelist | bool | false | Windows PE と Apple Mach-O の whitelist 項目に、ファイル hash だけでなく signer fingerprint も要求します。より強い方式ですが、正確な signer 値を収集できる場合だけ有効にしてください。Android/Linux の共有ライブラリは通常 hash-only で扱います。 |
| enableRemoteInjectionConfig (Pro) | bool | true | Pro 専用です。ポータルポリシーにより、検査周期、signer 要求、個別検査スイッチなど一部の Injection 設定をアプリ更新なしで調整できます。 |
| remoteInjectionConfigInterval | float | 300 s | Pro のリモート Injection 設定を再確認する周期です。0 の場合はアプリ起動時に 1 回だけ取得します。 |
| enableWindowsModuleIdentityScan | bool | true | 起動後に現れたすべてのモジュールをファイルハッシュで、Windows/macOS では署名者の指紋でも識別します(フィールド名は旧名のまま Windows ですが全ネイティブ対象に適用)。iOS/macOS はアプリバンドル内のイメージをゲームのコードとみなし、Android/Linux は共有ライブラリをハッシュで識別します。モジュールの識別方法を参照してください。 |
| scanIntervalSeconds | float | 1 s | Injection 検査を実行する基本周期です。値を下げると検出は速くなりますが、ランタイム負荷が増える場合があります。実際の適用値は安全な範囲に制限されます。 |
| windowsModuleIdentityScanIntervalSeconds | float | 5 s | 比較的重いネイティブモジュール識別検査の別周期です。モジュール列挙、hash 計算、signer 確認が対象端末で重い場合は、この値を上げてください。 |
| scanJitterPercent | float | 20% | 周期検査が毎回まったく同じ秒に走らないよう、設定した周期の前後で実行時刻を少し分散します。 |
| enableExecutablePrivateMemoryScan | bool | true | 通常のモジュールとして読み込まれていない実行可能なプライベートメモリを検知します。シェルコード型のペイロードを捕らえますが、実行可能領域だけでは証拠を累積するのみで、単独ではゲームを終了しません。Mono スクリプティングバックエンドのビルドでは、Mono JIT がまさにこの種のメモリを作るため、すべてのプラットフォームで自動的に無効になります。 |
| enableInlineHookScan | bool | false | 重要なネイティブ API エントリーポイントにパッチの痕跡がないか確認します。強いシグナルですが、overlay やセキュリティソフトも API を hook することがあるため、Strict 性質のビルドで互換性テスト後に有効化することを推奨します。 |
| enableThreadStartAddressScan | bool | true | ネイティブ thread が信頼モジュール外の疑わしいメモリから開始していないか確認します。対応プラットフォームで remote-thread 型の注入を検出する助けになります。 |
| enableExternalProcessHandleScan | bool | true | デバッガーやメモリエディターのような外部プロセスが、ゲームプロセスに危険な handle を持っていないか確認します。主に Windows で使用されます。 |
| detectionConfidenceThreshold | int | 70 | 強い Injection シグナルを即時に違反として扱う最小信頼度です。それより低いシグナルは連続・ウィンドウ判定で引き続き扱います。60〜100 に制限され、60 未満にするとプロセス内のあらゆる JIT エンジン(WebView、Lua、Mono)が違反のように見えます。 |
| enableWebRuntimeTamperScan (WebGL) | bool | true | WebGL 専用のブラウザランタイム検査です。WebGL では Native C++ モジュールスキャンを使えないため、ブラウザ側の改ざんシグナルを集める補助的なクライアント証拠として理解してください。 |
| webRuntimeScanIntervalSeconds (WebGL) | float | 1.5 s | WebGL ランタイム検査の基本周期です。ブラウザを過度に頻繁に検査しないよう、実際の適用値は 0.5〜30 秒に制限されます。 |
| webRuntimeScanJitterPercent (WebGL) | float | 20% | WebGL ランタイム検査が毎回同じ瞬間に実行されないよう、設定した周期の前後で実行時刻を少し分散します。 |
| WebGL probes | bools | true | WebGL ビルドで DevTools、clock hook、network hook、WebAssembly hook、storage hook、crypto API hook 検査を個別にオン/オフするスイッチです。 |
検知器がモジュールを識別する方法
検知器は数秒ごとにゲームプロセスに読み込まれた全モジュールを走査し、起動時の一覧と比較します。新しいモジュールはファイルハッシュで、Windows・macOS では署名証明書の指紋でも識別します。規則はモジュール自体だけを見てインストールフォルダー名は見ないため、正規のプログラムがインストールパスのせいで誤検知されることはありません。
| プラットフォーム | ゲーム自身のコードとみなす基準 |
|---|---|
| Windows | 起動時に存在し、実行時と同じ規則を通過したモジュール、OS 自身の構成要素(System32・SysWOW64・WinSxS)、そしてゲーム自身のネイティブモジュールです。ゲームのモジュールはビルドが整合性マニフェストに署名して収めたハッシュ一覧で識別し、フォルダーの位置は見ません。既知ベンダー(Steam、Discord、NVIDIA、RivaTuner、Nahimic、OBS、Epic、Ubisoft、EA、Overwolf、Medal、NVDA)の証明書チェーンが検証されたオーバーレイ・補助モジュールはサイレントな観測として記録され、それ以外で OS が信頼する証明書で署名されたモジュールは単独では終了せず、ポータルの判定待ち一覧に載ります。ゲームフォルダーに署名一覧にないネイティブファイルがあれば、起動時に Build Integrity 違反です。 |
| iOS / macOS | アプリ自身の .app バンドルに属するイメージと Apple プラットフォームイメージです。ビルド時に生成物は不要です。iOS 14.0 以上が必要で、それ未満では Editor の preflight が失敗します。 |
| Android / Linux | 起動時の共有ライブラリのうち実行時と同じ規則を通過したもの、システム・エンジンのランタイムライブラリ、Steam オーバーレイ、そしてアプリ自身のライブラリです。Linux ではビルドが署名したインベントリで(フォルダーの位置は見ません)、Android では OS だけが書けるインストール済みパッケージディレクトリでアプリ自身のライブラリを識別します。Android のシステム WebView 提供アプリもプラットフォーム構成要素として扱います。どのファイルにも属さない実行可能メモリも同じ走査で報告されますが累積判定のみで、単独では終了しません。Linux ホストレイヤーと Proton は上の Build Integrity ポリシー(既定 Monitor)に従います。 |
チェックは検知ファミリーごとに検知、走査済み正常、まだ時期でないの 3 つのいずれかで答えます。実際のサンプルだけがカウンターを動かし、実行されなかったチェックは以前の検知を消さず、まったく実行できなかったチェックは正常ではなくスキャナーの健全性問題として報告されます。
Pro: ポータルから検出モジュールを許可 / ブロック
enableServerWhitelist を有効にすると、Pro ビルドは起動時と serverWhitelistRefreshInterval ごとに署名付きの判定リストを 1 つダウンロードします。このリストは、顧客ポータル(インジェクション → 検知状況 → 検出モジュール)でチームが下した判定と、OZero が全顧客データから下した判定を統合したものです。
| 判定 | ゲームの動作 |
|---|---|
| Allow | そのモジュール(ハッシュ+署名者が一致)がネイティブの信頼リストに載り、プロジェクトの全端末で脅威として扱われなくなります。 |
| Block | このモジュールが読み込まれたゲームは繰り返し検知を待たずに即時終了します。チートツールと確定した場合のみ使います。 |
| Watch | ゲームには届きません。記録だけが蓄積され、後でより多くの根拠をもとに決められます。 |
- リストはライセンスにバインドされ、ライセンスサーバー鍵(Ed25519)で署名されます。SDK はアクティベーションで既に信頼している同じ公開鍵で検証します。
- 検証済みのリストは端末に保持され、オフライン起動でも適用されます。検証に失敗したリストは受け入れられず、検知自体が無効になることはありません。
- 一度も接続していない端末はビルド同梱のベースライン信頼リストだけを使います。その後の更新でサーバーに届けばリストを取得してキャッシュします。
- OZero がブロックしたモジュールを自プロジェクトが許可した場合、ポータルのOZero と自プロジェクトの判定が異なるとき設定がどちらに従うかを決めます(既定: OZero)。自プロジェクトがブロックしたモジュールは常にブロックされます。
- ABI 21 の SDK は Windows・macOS モジュールのコード署名主体(例:
Discord Inc.)も報告するため、ポータルは証明書の指紋の横に会社名を表示できます。iOS・Android のモジュールには読み取れる署名者がありません。 - 検知器が確認したがまだ対処していないモジュールは、ポータルの 観測されたモジュール 一覧にソース 終了前の候補 として載ります。プレイヤーが影響を受ける前に許可か遮断を決められます。端末でコード署名の証明書チェーンが検証されたモジュールは 信頼された署名 と表示され、identity 規則が自動的に終了することはなく、判定を待ちます。
スキャナー利用不可 (abort code 0x15)
ネイティブスキャナー自体が動作できない場合(設定の適用失敗、繰り返されるネイティブスキャンエラー、managed/native の契約不一致)、SDK は ModulationType.InjectionScannerUnavailable(値 10、abort code 0x15、message key injection_scanner_unavailable)を報告し、ForceQuitOnDetection が無効でもゲームを終了します。攻撃の検知ではなく、静かに壊れたスキャナーがゲームを無防備にするのを防ぐための動作です。プレイヤーには OZ-SEC-15 のようなサポートコードを表示し、ログには abort code を残してください。
PlayerPrefs 暗号化
保護が必要な新しい key は、Unity の PlayerPrefs ではなく OZeroSafePlayerPrefs に保存してください。よく使う Get/Set、HasKey、Delete、Save 形式はなじみのある名前で提供されますが、暗号化されたデータは既存の plain PlayerPrefs データとは互換性がありません。
using OZeroSDK.Security;
// Save a value
OZeroSafePlayerPrefs.SetInt("score", 4200);
OZeroSafePlayerPrefs.SetFloat("volume", 0.8f);
OZeroSafePlayerPrefs.SetString("username", "Hero");
// Read a value
int score = OZeroSafePlayerPrefs.GetInt("score", 0);
float volume = OZeroSafePlayerPrefs.GetFloat("volume", 1.0f);
string username = OZeroSafePlayerPrefs.GetString("username", "");
セーブファイルの暗号化
セーブファイルを暗号化するには、File.ReadAllText / File.WriteAllText の代わりに OZeroSV_File を使用してください。ファイルは書き込み時に自動的に暗号化され、読み込み時に復号されます。ロード時に改ざんの有無も検査します。
using OZeroSDK.Security;
string path = Application.persistentDataPath + "/save.json";
// Write encrypted file
OZeroSV_File.WriteAllText(path, jsonString);
// Read and decrypt file
string json = OZeroSV_File.ReadAllText(path);
developerSecret を変更しないでください。developerSecret は OZeroSafePlayerPrefs と OZeroSV_File データの暗号化キーを作る基準値です。リリース後にこの値を変更すると、既存のバージョンで保存した保護データを新しいビルドで復号できません。
4
インゲーム変数の保護(Secure Types)
Secure Types は、通常の C# 変数型を暗号化された型に置き換えます。値が Native C++ ヒープに保存されるため、Cheat Engine のようなツールではメモリをスキャンしても見つけることができません。型の名前を変更するだけで、残りのコードはそのまま動作します。
サンプルコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OZeroSDK.Security;
public class PlayerStats : MonoBehaviour
{
[SerializeField] OZeroSV_Int Gold = 5000;
[SerializeField] OZeroSV_Float Speed = 3.5f;
[SerializeField] OZeroSV_Int HP = 1000;
}
サポートタイプ
| 既存 | OZero 適用後 |
|---|---|
| int | OZeroSV_Int |
| long | OZeroSV_Int64 |
| uint | OZeroSV_UInt |
| ulong | OZeroSV_UInt64 |
| short | OZeroSV_Short |
| ushort | OZeroSV_UShort |
| byte | OZeroSV_Byte |
| float | OZeroSV_Float |
| double | OZeroSV_Double |
| decimal | OZeroSV_Decimal |
| bool | OZeroSV_Bool |
| string | OZeroSV_String |
| Vector2 | OZeroSV_Vector2 |
| Vector3 | OZeroSV_Vector3 |
| byte[] | OZeroSV_Buffer |
7
セキュリティイベント処理(選択)
基本的に OZero は脅威を検知すると、設定された対応ポリシーに従ってアプリを終了するかログのみを残します。直接警告画面を表示したり、独自のサーバーログを送信したり、終了直前に保存処理をしなければならない場合はコールバックを登録できます。コールバックは OZeroSecurityEvent を通じて変調タイプ、中断コード、メッセージキー、詳細メッセージ、終了予定の可否を一緒に伝達します。
using UnityEngine;
using OZeroSDK.Security;
public class SecurityHandler : MonoBehaviour
{
void OnEnable()
{
// RegisterUserCallback runs on the user chain only.
// The built-in default handler runs independently and cannot be silenced.
OZeroSecurityManager.Instance.RegisterUserCallback(OnThreatDetected);
}
void OnDisable()
{
OZeroSecurityManager.Instance.UnregisterUserCallback(OnThreatDetected);
}
void OnThreatDetected(OZeroSecurityEvent evt)
{
// evt contains Type, AbortCode, AbortCodeHex, MessageKey, Message, and WillAbort.
Debug.LogWarning(
$"OZero threat: {evt.Type} {evt.AbortCodeHex} {evt.Message}");
switch (evt.Type)
{
case ModulationType.SpeedHack:
// e.g. kick the player, show warning, report to server
break;
case ModulationType.BuildIntegrity:
// evt.WillAbort is usually true for fatal build integrity violations.
break;
case ModulationType.Injection:
break;
}
if (evt.WillAbort)
{
// Last chance to flush your own analytics or save state.
}
}
}
OZeroSecurityEvent、ModulationType、OZeroAbortCode の全体リストは API レファレンスに文書化されています。
evt.WillAbort が true であれば現在の対応ポリシー上、コールバック以降にアプリが終了されます。この時は独自の analytics flush や保存処理のみを短く実行してください。
脅威が検知されると、OZero はまず SDK の基本の対応ポリシーを適用し、プロジェクトで登録したコールバックとインスペクターのイベントにも同じセキュリティイベントを伝達します。直接警告画面を表示したりサーバーログを残したい場合はコールバックを登録してください。アプリの終了の可否は Config Dashboard の Response 設定と evt.WillAbort 値で確認できます。
ポータルポリシーコールバック
Customer Portal のポリシーは段階的に運用できます。Observe は証拠のみを記録し、Callback はサーバー発行の policy action をゲームへ配信し、Device Block は以降のサーバー検証で対象デバイスをブロックします。より強いデバイスブロックを使う前に、ゲーム側で警告表示、マッチメイキング制限、再ログイン要求、サポート案内を処理したい場合は Callback を使用してください。
using UnityEngine;
using OZeroSDK.Security;
public class PolicyActionHandler : MonoBehaviour
{
void OnEnable()
{
OZeroSecurityManager.Instance.RegisterUserPolicyActionCallback(OnPolicyAction);
}
void OnDisable()
{
OZeroSecurityManager.Instance.UnregisterUserPolicyActionCallback(OnPolicyAction);
}
void OnPolicyAction(OZeroPolicyActionEvent evt)
{
Debug.LogWarning(
$"Policy callback: {evt.Module}, score={evt.Score}, reason={evt.Reason}");
if (evt.Score >= 80)
{
// Show your own UI, limit sensitive actions, or ask the player to reconnect.
}
}
}
次のステップ
これで OZero の核心の保護機能が実行中です。API レファレンスですべてのクラス、メソッド、設定オプションを詳しく確認してみてください。
トラブルシューティングリファレンス
Use this section when an OZero dialog appears, a security log is reported, or the app closes for a security reason. Start with the code shown on screen or in the log, then follow the first checks below.
Support Codes
Support codes are short labels shown in OZero dialogs and logs. When a player sends this code to support, the development or QA team can quickly identify which broad area to check. OZ-SEC-* means a security event was reported, and OZ-MV-* means an online or managed verification state needs attention.
| Code | Category | What to check |
|---|---|---|
| OZ-SEC-01 | Memory protection | Check whether protected values were changed by an unsupported path, a test tool, or an incorrect Secure Types integration. |
| OZ-SEC-02 | Injection or hook | Check whether an overlay, debugger, modding tool, or other external program was attached. Add exceptions only after QA confirms the program is trusted. |
| OZ-SEC-0A | Build integrity | Check whether the build, manifest, signing information, native variant, or packaged files changed after the release build was prepared. |
| OZ-SEC-0C | Speed or time change | Check speedhack tools, device clock changes, direct Time.timeScale writes, and legitimate slow-motion or pause flows. |
| OZ-SEC-0E | Device or install policy | Check the install source, store package identity, emulator/root/jailbreak policy, and device-binding support process. |
| OZ-SEC-0F | Physics check | Check whether movement limits, collision layers, dash, knockback, or vehicle movement are tuned for the actual game rules. |
| OZ-SEC-10 | Runtime environment | Check whether the app is running in a supported device, browser, emulator, debugger, or platform test environment. |
| OZ-SEC-13 | Steam verification | Check Steam launch state, AppID, ownership verification, required Steamworks files, and network connection. |
| OZ-SEC-15 | インジェクションスキャナー利用不可 | 攻撃ではありません。ネイティブのインジェクションスキャナーが動作できない状態です(設定未適用、繰り返されるスキャン失敗、managed/native の契約不一致)。SDK とネイティブバイナリが同じパッケージのものか確認し、ゲームを再インストールしても続く場合はお問い合わせください。 |
| OZ-SEC-1F | Unknown category | Collect the platform, SDK package version, native ABI, Player log, ozero_abort.txt, and exact reproduction steps. |
| OZ-MV-LOCAL | Managed verification | Check license activation, server/network access, registered app identity, platform signing information, and the currently applied variant manifest. |
Abort Codes
Abort codes are stable categories used in logs, callbacks, and OZ-SEC-* support codes. They tell the development team which protection area responded without exposing detailed evidence to the player.
| Code | Category | Meaning |
|---|---|---|
| 0x01 | Memory protection | Protected memory value changed unexpectedly. |
| 0x02 | Injection or hook | Unexpected module, hook, or runtime injection signal detected. |
| 0x0A | Build integrity | Build integrity validation failed. |
| 0x0C | Speed or time change | Suspicious execution speed, time scale, system clock, or trusted-time anomaly detected. |
| 0x0E | Device or install policy | Device binding or install-source policy rejected the current environment. |
| 0x0F | Physics check | Abnormal physics behavior exceeded the configured policy. |
| 0x10 | Runtime environment | Unsupported or unsafe runtime environment detected. |
| 0x13 | Steam verification | Steam ownership or ticket validation failed. |
| 0x15 | インジェクションスキャナー利用不可 | インジェクションスキャナー自体が動作できませんでした。SDK は無防備で実行し続ける代わりに fail-close で終了します。 |
| 0x1F | Unknown category | A security event did not match a more specific public category. |
For API fields and callback examples, see OZeroAbortCode & Event Messages.
解決手順
| Step | Action | Expected evidence |
|---|---|---|
| 1 | Record the support code shown on screen or in the log, plus the platform. | The screenshot or ticket should include the code, OS, Unity version, SDK package version, and whether the build is Development or Release. |
| 2 | Check ozero_abort.txt and the Player log first. | These files can still help when the app closes before a popup appears. |
| 3 | If the issue is reproducible in QA, enable Enable Failure Diagnostics, reproduce once, then disable it again. | The latest ozero_*_failure.log helps identify which protection area responded. Use this file only for QA or support investigation. |
| 4 | Run Window > OZero Security > Check Setup before changing policies. | Preflight can catch missing required packages, manifest/signing mismatch, platform settings, ProGuard/R8 settings, native plugins, and obvious license setup issues. |
| 5 | For Pro or managed verification cases, compare portal registration with the actual build information. | Confirm package/app ID, platform signing information, SDK package, native ABI, active variant manifest, license tier, server connection, and any downgraded or limited state. |
| 6 | After the fix, rerun the matching platform QA scenario. | Capture survival timing, Managed UI visibility, simulated or real attack result, popup countdown, and final logs before closing the ticket. |