アプリ開発者は、Appleが提供する2つのツール「App Attest」と「DeviceCheck」を活用することで、不正行為を最小限に抑えることができます。アプリへの不正な改変や、ユーザーによるプレミアムコンテンツの不正取得を防ぐために、これらのツールを活用する方法をご紹介します。
アプリ開発者として、自分の作品から収益を得る方法はいくつかあります。しかし、誰もが喜んでお金を払いたいとは思わない一方で、有料のプレミアム機能にアクセスしたいと考える人もいるかもしれません。
開発者はこうした行為を回避しようと努めています。そこでAppleのApp AttestとDeviceCheckが役立ちます。
Apple の DeviceCheck フレームワークを使用すると、許可されたユーザーのみがプレミアム コンテンツやプロモーションにアクセスできるようになります。
デバイスチェック
Apple は、アプリがプレミアム アプリ機能の不正使用の試みを減らすのに役立つ DeviceCheck フレームワークを提供しています。
DeviceCheck は、アプリ内のプロモーション オファーにおける不正行為を軽減するのに役立ちます。
例えば、アプリがプロモーションやプレミアムコンテンツを提供している場合、一部のユーザーはこれらの機能を悪用して複数の無料アイテムを入手しようとする可能性があります。アプリをアンインストールしてから再インストールすることで、こうした行為を働く可能性があります。
DeviceCheck フレームワークを使用すると、アプリは特定のハードウェア デバイスがすでにプロモーション オファーを受け取っているかどうかを確認できます。
これらのチェックは、各AppleデバイスのSecure Enclaveに紐付けられています。Appleアカウントと秘密暗号鍵と組み合わせることで、認証が確実に行われます。
このチェックには以下が含まれます。
- Appleがタイムスタンプとともに保存した2つのデバイス状態ビット
- デバイスごと、開発者ごと
- ハードウェアデバイスのリセット後も持続
Appleが保存する2つのビットは、各Apple開発者を、アプリごとに以前に登録されたプロモーションの既知の状態に結び付けます。タイムスタンプと併せて、これらのビットを自由に使用することで、アプリがプロモーションのステータスを判断できます。
DeviceCheck は、アプリ開発者ごとにデバイスごとにデバイスを追跡します。
Apple デバイスが完全に工場出荷時の状態にリセットされた場合、DeviceCheck の状態はデバイスのリセット後も保存されます。
これらのチェックは、特定のプロモーションが以前に任意の Apple デバイスの任意の Apple アカウントの任意のアプリによって使用されたかどうかを確認するためにアプリで使用できます。
アプリの証明
App Attest も DeviceCheck.framework の一部であり、アプリが備えている特定のサービスを追跡して、そのサービスがアプリで認識されるかどうかを判断できます。
App Attest を使用するには、ユーザーのデバイスからハードウェアベースのトークンと App Attest リクエストを受信するサーバーまたはクラウドベースのサービスが必要です。サーバーは、これらのアプリリクエストを検証のために Apple App Attest サーバーに転送する必要があります。
Apple サーバーがアプリとサービスが有効であると返すと、サーバーは送信デバイスにリクエストが有効であることを通知します。
各リクエストは特定のデバイス ハードウェア情報に関連付けられているため、他のデバイス向けにリクエストを偽造またはコピーすることはできません。
App Attest は、プレミアム アプリやサービス機能の不正なコピーがデバイス間でコピーされるのも防止します。
3つの簡単な作品
App Attest は、リクエストが正規の承認済み Apple デバイスから送信されたものであることを確認するためにアプリが使用できる 3 つの重要な情報を提供します。
- 純正Appleデバイス
- 本物のアプリケーションID
- 信頼できるペイロード
正規の Apple デバイスを確認することで、アプリとプレミアム コンテンツが実際に実際の Apple デバイスで実行されていることを確認できます。
認証アプリケーションIDは、リクエストを送信しているアプリがあなたのアプリであり、正規のコピーであることを確認します。つまり、App Storeからダウンロードされた正規のアプリです。
信頼できるペイロードをチェックすることで、プレミアム機能またはプロモーション コンテンツが承認され、購入され、改ざんされていないことを確認できます。
これら3つの情報を使用することで、アプリはユーザーがコンテンツを確実に利用できるようにすることができます。これにより、ハッカーやジェイルブレーカーが、有料で購入・承認されたプレミアムコンテンツを別のAppleデバイスにダウンロードしたり再利用したりするのを防ぐことができます。
正規のデバイスチェックは、Secure Enclave で使用されるデバイス上のセキュアキーペアの検査によって行われます。この検査は、有効なキーペアを使用して生成されたデバイスからの App Attest リクエストと組み合わせられます。
安全なキー ペアは、暗号化を使用して安全なキーを作成し、ネットワーク経由で送信する、 公開キー インフラストラクチャ(PKI)と呼ばれるものの一部です。
安全なキーとデジタル署名を使用することで、アプリとデバイスは、リクエストが要求元の送信元であることを確認できます。
PKI は非常に安全で、世界で最も高性能なスーパーコンピュータでもそれを解読するには何年もかかります。
アプリがApp Attestリクエストを行う際、セキュアキーを使用してリクエストを送信できます。セキュアキーはサーバーによって検証されます。セキュアキーはインストールごとに固有であり、デバイス間で同期またはコピーされることはありません。
各リクエストごとに、検証のために各リクエストとともに、 エンコードされた各アプリのバンドル IDのコピーも送信されます。
キーの証明を生成しています。
アプリにApp Attestを追加する
Xcode でアプリに App Attest を追加するには、まず各プロジェクト ターゲットのフレームワーク ペインの [ビルド情報] タブに DeviceCheck.framework を含める必要があります。
アプリでApp Attestを使用するには、アプリがSecure Enclaveを搭載したデバイスで実行されている必要があります。そのため、実際に使用する前に、アプリでApp Attestを使用できるかどうかを必ず確認してください。
アプリに App Attest を追加する手順も 3 つあります。
- AppAttestキーの生成
- キーの検証
- アサーションの生成と検証
アプリのコードに AppAttest キーを作成するには、次のようにクラス オブジェクト.shared
のプロパティを使用しますDCAppAttestService
。
let appAttestService = DCAppAttestService.shared
appAttestService
これにより、プロパティから名前が付けられたローカル変数が作成され.shared
、共有サービス オブジェクトのコピーが保存されます。
プロパティのインスタンスを取得したら.shared
、それを使用してキーを作成できます。
App Attest 用のデバイス キーを生成しています。
上記のコードでは、まずDCAppAttestService
クラスの共有インスタンスを取得します。次に、そのプロパティをチェックして.isSupported
、このデバイスでAppAttestが利用可能かどうかを確認し、メソッドでキーを生成します.generatekey
。
エラーが返された場合は.generatekey
、エラーをチェックして処理します。それ以外の場合は、キーが で返されますkeyId
。
キーを取得したら、後で使用するためにキーを保管できます。おそらく、以前に定義して作成したオブジェクトに保管することになります。
DeviceCheck.framework は、Swift ではなく Objective-C 言語を使用している場合にも Objective-C インターフェースをサポートします。
.isSupported
プロパティが返されるNO
かキーが返される場合、nil
アプリで AppAttest を使用できません。
NO
デバイスにセキュア エンクレーブが搭載されている場合でも、コードが を返す場合があることに注意してください.isSupported
(通常、コードがアプリ拡張機能から呼び出される場合)。
アプリはこうしたケースにも対応できるように準備しておく必要があります。このような状況では、呼び出し元が信頼できないと想定し、一連のリスク評価ルールに基づいて独自のコードロジックを作成し、プレミアム機能を許可するかどうかを判断してください。
.isSupported
このアプローチは、プロパティが を返す場合の次善の検証ですNO
。
キーを検証する
上記のコードから有効なキーを取得できたと仮定すると、次のステップはキー を検証または証明することです。
これを実行するには、アプリでワンタイムのサーバーチャレンジを作成する必要があります。このチャレンジは、サーバーからのチャレンジによって生成したキーを認証し、ユーザーアカウント情報と組み合わせてキーを検証するように設計されています。
キー証明の発生ごとにこれを実行するためのサーバー側コードも考案する必要があります。
キー構成証明は、中間者攻撃やリプレイ攻撃を防ぐことで、セキュリティをさらに強化します。
このプロセスの最初のステップは、鍵の認証情報を生成することです。上記と同じアプリ認証サーバーオブジェクトを使用しますが、.attestKey
メソッドを使用します。
このメソッドを使用すると、元のkeyID
、クライアント データ ハッシュ、attestationObject
、およびメソッドが入力として受け取るオプションのエラー変数を渡します.attestKey
。
戻ったときに、 をattestationObject
サーバーのチャレンジに使用できます。
この方法の目的は.attestKey
、デバイスの秘密鍵を使用して、鍵と特定のデバイスに紐付けられた不透明なハードウェア認証リクエストを作成することです。
このハードウェア認証は、ハードウェア検証のためにApple認証サーバーに送信されます。検証が完了すると、Appleサーバーは匿名の認証オブジェクトをアプリに返します。
Apple のサーバーだけが、送信された情報に基づいてハードウェア レベルでデバイスを検証する方法を知っているため、ハッカーがリクエストを傍受して、プレミアム機能を有効にする誤検知を返すことは非常に困難になります。
アプリは Apple からの応答を受信し、それが有効であることを確認したら、最終検証のためにカスタム ペイロードとともに応答をサーバーに送信する必要があります。
このかなり複雑なプロセスは、Apple のハードウェア検証と秘密鍵と組み合わされており、誰かがプレミアム機能をハッキングして不正なコンテンツを有効にすることが非常に困難になります。
Apple の WWDC 2021 ビデオ「App Attest と DeviceCheck による不正行為の軽減」では、このプロセスについてさらに詳しく説明しています。
Apple Developer アカウントドキュメントの「機能の構成」領域に、 「DeviceCheck 秘密キーを作成する」セクションもあります。
DeviceCheck フレームワークのドキュメントには、確認する必要がある追加のセクションが 4 つあります。
- デバイスごとのデータへのアクセスと変更
- 詐欺リスクの評価
- アプリの整合性を確立する
- サーバーに接続するアプリの検証
エラー処理
上記のコードでは、Apple の DeviceCheck API の一部がオプションのエラー コードを返すことがわかりました。
アプリはこれらのコードを処理し、エラーが発生した場合にユーザーに通知する必要があります。
DeviceCheck フレームワークの
クラスDCDevice
とクラスのドキュメントを確認してください。DCError
を返すDeviceCheckフレームワークAPIから、プロパティDCError
の値を取得することで、ユーザーが表示可能なエラーコードを取得することもできます。これは、事前定義されたAppleエラーコードのセットにマッピング可能な(数値)
.Code
として定義されています。enum
標準の Swift/Ccase
ステートメントを使用すると、エラー コードの結果を、アプリがユーザーに表示するユーザー表示可能な文字列にマップできます。
DCError
現在、 Apple によって設定された
定義済みコードが 5 つあります。
- 機能サポートされていません
- 無効な入力
- 無効なキー
- サーバーが利用できません
- 不明なシステム障害
featureUnsupported
DeviceCheck API の一部またはすべてが利用できないことを意味します。invalidKey
使用しようとしたキーが失敗したことを意味します。
Apple API またはキー構成証明からエラーが返された場合、アプリは適切なローカライズされたテキスト文字列をユーザーに表示し、動作しなかった理由を通知する必要があります。
エラー発生後にグローバル変数をチェックして、DCErrorDomain
最後に発生したエラーのドメインを特定することもできます。
エラードメインは、エラーを分類したカテゴリDCErrorDomain
と考えてください。文字列を使用することで、発生したエラーの種類に関する有用な追加情報をユーザーに提供できます。
DeviceCheckとAppAttestは、Appleアプリ開発に歓迎される追加機能です。アプリでこれらを使用することで、余分な手間をかけずにプレミアム機能と収益を確保できます。