セキュリティ
金庫室の構造と、侵入した場合に何が見つかるか。
最終更新日:2026年9月21日 · AssuredAuth(CircleRoll LLC提供)
これは、AssuredAuthが二要素認証情報、パスワード、カード情報をどのように保護するかについての公式な説明です。セキュリティに関心のある読者が、アプリと公開されているテストベクトル(hello@assuredauth.com宛てにリクエストすれば、レビュー担当者は誰でも入手可能)に対して、すべての主張を検証できるように書かれています。ここに書かれているのは真実のみであり、それ以上のことは述べていません。攻撃を受けないことを主張するものではなく、パーセンテージで保証するものでもありません。
簡単に言うと、保管庫はあなたのスマートフォンの中にのみ存在します。保管庫内のすべての値は、スマートフォンのセキュリティハードウェアが保持し、外部に持ち出すことのできない鍵で暗号化されています。弊社は保管庫サーバーを運用しておらず、コピーも鍵も一切保持していません。バックアップファイルは、どこにも保存されないパスフレーズで暗号化された後にのみ、スマートフォンから外部に送信されます。
問題を報告する: hello@assuredauth.com. 末尾の「弱点の報告」を参照してください。
1. 何が何で暗号化されているのか
| データ | スマートフォンで | キー |
|---|---|---|
| 二段階認証の秘密情報(TOTP/HOTP/Steamシード) | スマートフォンでキーチェーン(iOS)/ Android キーストア対応ストア | キープラットフォームのハードウェアに紐づけられたキー。データベースの行には参照(secretRef)のみが格納され、シードは格納されない。 |
| パスワード(パスワードの値、メモ) | スマートフォンで封印された行: AES-256-GCM、値ごとにランダムな96ビットのnonce | キーランダムな256ビットのデータキーは、§2のハードウェアキーでラップされている。 |
| カード情報(番号、有効期限、カード名義人、CVCコード) | スマートフォンでパスワードと同じシールです。CVCはオプションであり、入力した場合にのみ保存されます。 | キー同じデータキー |
| メタデータ(サービス名、ユーザー名、アイコン、並び順) | スマートフォンでアプリのデータベース(SwiftData / Room) | キーオペレーティングシステムのファイル暗号化によって保護されています。非機密情報として扱われます。 |
| バックアップファイル(.authbackup) | スマートフォンでどこに置いたとしても:ファイル、iCloud Drive、Google Drive appDataFolder、共有シート | キーパスフレーズから生成されたキー(§3)。AppleとGoogleは封印されたファイルのみを受け取ります。 |
| Watch / Wear コンパニオン | スマートフォンで時計本体のキーチェーン / 暗号化された共有設定 | キーウォッチプラットフォームのキー。プラットフォームのペアリング済みデバイスチャネルを介して転送されます。 |
| デスクトップ拡張機能のトラフィック(リクエストに応じてワンタイムコードを提供) | スマートフォンで保存されず、エンドツーエンドで暗号化された封筒として中継される。 | キーペアリングごとにX25519キーペア、キーチェーン/キーストアに秘密鍵が格納されます。リレー側では暗号文のみが表示されます。 |
診断機能には、シークレットを受け入れるメソッドはありません。分析イベントには、ボールトフィールドは含まれません。どのビルドにおいても、ボールトの値がログに書き込まれることはありません。
2. 各プラットフォーム上のキーの場所
iOS。 データキーは、セキュアエンクレーブ (kSecAttrTokenIDSecureEnclave) 内で生成されたキーでラップされ、アクセス制御は .privateKeyUsage + .userPresence、アクセス権限は …ThisDeviceOnly に設定され、アプリの共有キーチェーンアクセスグループに保持されるため、AutoFill 拡張機能で同じキーを使用できます。プライベートキーは、アプリ、バックアップ、またはデバッガーによってエンクレーブから読み取ることはできません。エンクレーブは、ユーザーが存在する場合 (Face ID、Touch ID、またはデバイスのパスコード) にのみ、そのキーの使用を許可します。ThisDeviceOnly とは、iCloud または iTunes の電話のバックアップにはキーが含まれないことを意味します。復元された電話は空のボルトから始まり、バックアップファイルとパスフレーズの入力を求められます。パスコードのない電話では、.userPresence キーをゲートすることはできません (Enclave が作成を拒否するため)。シミュレーターも設計上同じ手順を踏みます (プレゼンスプロンプトは、どのテストでも回答できないアラートです)。そこでは、データキーは単なるデバイス専用のキーチェーン項目です。バックアップには含まれず、電話がロックされている間は読み取りできませんが、2 番目のプロンプトはありません。セキュリティ画面にはまさにその旨が表示され、パスコードを設定するように提案されます。
Android。 データキーは、デバイスにStrongBoxがある場合はStrongBoxで生成されたAndroidKeyStore AES-256キーでラップされ(そうでない場合はTEE)、setUserAuthenticationRequired(true)と生体認証またはデバイス認証情報による認証の有効期間が30秒、setUnlockedDeviceRequired(true)とsetInvalidatedByBiometricEnrollment(true)がオンのままになっています。最後のフラグは負荷を支えるものではなく、正直なものです。Androidは、使用のたびに生体認証を要求するキーにのみこれを適用するため、デバイス認証情報が許可されているこの30秒キーでは何も変わりません。他人の指が入らないようにするのは、登録にPINが必要であり、画面ロックを解除するとキーが完全に無効になることです。キーストアキーはエクスポートできず、Androidのクラウドバックアップから除外されます。アプリが独自のビューで命名するドメイン(webDomain)は、既知のブラウザからのみ有効です。他のパッケージからは、どのアプリでも任意のドメインを主張できるため、システムがそのパッケージに対して検証したドメイン(デジタルアセットリンク)である必要があります。
これは、盗まれたデータベースファイルにとって何を意味するのか。 SQLiteファイルと封印された行は暗号化されています。それらを開く鍵は、ファイルの送信元となったスマートフォンのセキュリティハードウェアに保存されており、ファイルと一緒にコピーすることはできません。オフラインで推測できるものは何もありません。データキーはランダムに生成され、人が選択したものから派生したものではありません。
3. バックアップファイル
バックアップはスマートフォンから外部に持ち出される唯一のデータであるため、原理的にはオフライン攻撃が可能な唯一の箇所です。この設計では、そのような攻撃のコストを高くし、攻撃者が利用できる要素を最小限に抑えています。
- パスフレーズは12文字以上である必要があります(それより少ない文字数だとシートに拒否され、強度を示すバーが表示されます)。
- パスフレーズのヒントは、ファイル内にもアプリ内にも一切保存されていません。
- 書き込まれるファイルごとに、新たに生成されたランダムな16バイトのソルトと12バイトのノンス。
- 暗号化全体がAES-256-GCMで行われているため、パスフレーズが間違っていたり、ファイルが破損していたりしても拒否され、決して復号化されてゴミデータになることはありません。
- ヘッダー(フォーマット、バージョン、KDFパラメータ、ソルト)は追加の認証データとしてGCMタグにバインドされるため、ワークファクターが編集されて下げられたファイルは開かれません。
このファイルはJSON形式で、どのテキストエディタでも読み取ることができます。暗号化された部分だけが不透明です。アプリが削除された5年後にこのファイルを見つけた人は、どのように暗号化されたかを正確に把握し、OpenSSLやArgon2ライブラリを使って開くことができます。
フォーマットv1(バージョン1.0で出荷されたもので、読みやすさは維持されています)
{
"format": "authbackup",
"version": 1,
"kdf": "PBKDF2-HMAC-SHA256",
"rounds": 600000,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| ステップ | バイト |
|---|---|
key | PBKDF2-HMAC-SHA256(passphrase as UTF-8, salt, 600000 rounds, 32 bytes) |
aad | UTF-8("authbackup:1:600000:") ‖ salt (Base64エンコードされていない、生のソルトバイト) |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); タグ16バイト、別々に保存 |
plaintext | UTF-8 JSON、キーはソート済み: {"accounts":[…],"exportedAt":"…Z","passwords":[…],"version":1} |
互換性に関する注意:Android 1.0 では、v1 のバリアントである、小文字の kdf、タグキーなし(暗号文に付加される 16 バイトのタグなし)、追加データなしの形式で書き込まれていました。両プラットフォームともこれらのファイルを読み込み続け(タグがない場合:最後の 16 バイトを分割し、空の AAD で開き、kdf を大文字小文字を区別せずに比較)、現在は上記のレイアウトのみを書き込むようになっています。
フォーマットv2(現行バージョン、新規バックアップのデフォルト)
{
"format": "authbackup",
"version": 2,
"kdf": "Argon2id",
"memoryKiB": 65536,
"passes": 3,
"lanes": 1,
"salt": "<base64, 16 bytes>",
"cipher": "AES-256-GCM",
"nonce": "<base64, 12 bytes>",
"ciphertext": "<base64>",
"tag": "<base64, 16 bytes>"
}
| ステップ | バイト |
|---|---|
key | Argon2id(version 0x13, passphrase as UTF-8, salt, m = 65536 KiB, t = 3, p = 1, tagLength 32, no secret, no associated data) |
aad | UTF-8("authbackup:2:argon2id:65536:3:1:") ‖ salt |
ciphertext, tag | AES-256-GCM(key, nonce, plaintext, aad); タグ16バイト、別々に保存 |
plaintext | UTF-8 JSON、キーはソート済み: {"accounts":[…],"cards":[…],"exportedAt":"…Z","passwords":[…],"version":2} |
Argon2id は、両プラットフォームでベンダー提供されているリファレンス C 実装 (phc-winner-argon2、CC0) です。64 MiB と 3 回のパスで、現在のスマートフォンでは約 1 秒かかります。各推測には、どのハードウェアでもそのメモリと時間が費やされます。これは、PBKDF2 が GPU リグに対して欠いている特性であり、v2 が存在する理由です。リーダーは知らないキーを無視するため、v2 ボディを与えられた v1 リーダーは、カードを見ることはありません。
証拠
3 つのテストベクトルファイル (backup v1、backup v2、および Argon2id) は、両方のアプリとは独立した第 3 の実装 (PBKDF2 および AES-GCM 用の Node の OpenSSL、生成時に参照実装の公開された回答と照合される WebAssembly Argon2id) によって生成されます。各ファイルには、パスフレーズ、ソルト、nonce、平文、派生キー、AAD、期待される暗号文とタグ、および完全なファイルが含まれています。iOS と Android のユニットテストでは、同じファイルを読み込み、同じバイトを検証します。そのため、一方のプラットフォームで封印されたバックアップは、他方のプラットフォームで開くことが証明され、想定されるのではなく、3 つのプラットフォームすべてで一致したとしても、同じ間違いが 2 回繰り返されたわけではありません。付属ツールは、同じ第3の実装で実際に電話機が書き込んだファイルを開き、上記のルール(フォーマットのキーと完全に一致し、ヒントや名前は存在できない。16バイトのソルト、12バイトのノンス、16バイトのタグは別々に保存される。バージョン2は正確に64 MiB / 3 / 1。間違ったパスフレーズは拒否される)とヘッダーを照合します。自動化されたiOS実行では、シミュレーター上に1つ書き込み、そのように開き、シミュレーターのアプリコンテナ、アプリグループコンテナ、キーチェーンデータベースをUTF-8とUTF-16としてシードされたすべてのパスワードとカード番号で検索します(ヒット数0)。
4. 脅威モデル
| 状況 | 持っているもの | 得られるもの |
|---|---|---|
| 紛失または盗難された電話、ロックされた電話 | 持っているものデバイス、データベースファイル、封印された行 | 得られるもの暗号文。ラッピングキーはセキュアエンクレーブ/ストロングボックスに格納されており、デバイスのロック解除と新たな生体認証またはパスコードの入力後にのみ解放されます。リモートで電話をワイプする(「端末を探す」/「デバイスを探す」)と、キーマテリアルも一緒に破壊されます。 |
| 盗まれたバックアップファイル | 持っているものクラウドアカウント、メール、ラップトップからの.authbackupファイル | 得られるもの少なくとも12文字のパスフレーズから生成された鍵で暗号化されたAES-256-GCMの本体。ファイルごとにソルトを使用し、Argon2idを64 MiB × 3パス(v2)またはPBKDF2を60万ラウンド(v1)実行します。ヒント、ユーザー名、アカウントリストは平文で公開されません。推測するたびに完全な導出が必要となり、近道はありません。強力なパスフレーズが防御のすべてであり、アプリのシートにもその旨が記載されています。 |
| 画面ロックが解除された盗難端末 | 持っているもの手に持ったスマートフォン、ロック解除済み | 得られるものコード一覧。保管庫(パスワード、カード)はアプリロックの背後にあり、自動ロックタイマー(即時/1分/5分)で再ロックされます。復号化された値は、画面に表示されている間のみメモリに存在します。アプリが開いている場合でも、自動入力とプレーンテキストのエクスポートには新しい生体認証が求められます。この点が気になる場合は、「即時」でアプリロックをオンにしてください。 |
| 同じ電話に悪意のあるアプリがインストールされている | 持っているもの別のアプリのサンドボックス、クリップボード、アクセシビリティ、またはオーバーレイのトリック | 得られるもの当社のファイルを読み取ることはできません(プラットフォームのサンドボックス化)。また、当社のキーを使用することはできません(キーは当社の署名IDとユーザーの存在に紐づいています)。コピーは30秒後にクリップボードからクリアされます。Androidでは、コピーは機密情報としてフラグ付けされ、クリップボードの履歴から除外されます。Vault画面はAndroidでFLAG_SECUREに設定され(スクリーンショットなし、画面録画なし、スイッチャーは空白)、iOSではスイッチャーのサムネイルが空白になります。Androidの自動入力は、システムが保存されたドメイン(デジタルアセットリンク)に対して検証したアプリにのみ提供されるため、類似アプリにはパスワードが提供されません。 |
| フィッシングページ | 持っているもの保存したサイトに似たサイト | 得られるもの何も入力されません。マッチングは登録可能なドメイン(アプリに同梱され、更新される公開サフィックスリスト)で行われます。login.example.com と example.com は一致しますが、example.com.evil.net と examp1e.com は一致しません。アプリ内ブラウザも同じ方法でマッチングを行い、入力を要求したフレームにのみ入力し、入力時にそのフレーム自身のオリジンと再チェックします。登録可能なドメインを持たないホスト(IP アドレス、ローカルネットワーク上の単なる名前)は完全に一致し、緩い一致はありません。iOS の自動入力機能には、Apple の関連ドメインチェックが追加されています。似たようなものに手動で貼り付ける必要があるパスワードは依然としてリスクであり、アプリはそれを取り除くことはできず、手助けを避けることしかできません。 |
| 自社サーバー | 持っているもの— | 得られるもの保管庫サーバーは存在しません。AssuredAuthにはアカウントもサインイン機能も保管庫のコピーもないため、お客様の情報が弊社側に盗まれたり解読されたりする心配はありません。サーバー側で実行されるものは2つありますが、どちらも保管庫には一切触れません。1つはデスクトップ拡張機能用のリレーメールボックスで、エンドツーエンドで暗号化された封筒(読み取られると削除されるワンタイムコード。リレーは鍵を保持しません)を保存します。もう1つはオプションのプライベート接続の出口サーバーで、トラフィックを転送し、アクセスログは一切保持しません。 |
| 召喚状または政府からの要請 | 持っているもの私たち宛ての法的措置 | 得られるもの引き渡すものは何もありません。金庫も鍵もパスフレーズもバックアップも一切持っていません。そう言わざるを得ない状況には追い込まれますが、存在しないものを提出するよう強制されることはありません。 |
5. クリップボード、スクリーンショット、メモリ
- コピーすると、値がクリップボードに30秒間コピーされ、その後、まだ自分のものである場合はクリアされます。Androidでは、クリップはEXTRA_IS_SENSITIVEとしてマークされるため、システムはクリップボードのプレビューと履歴からそれを非表示にします。iOSでは、ペーストボード項目はローカルのみで(他のデバイスにハンドオフされません)。
- Androidでは、Vault画面(パスワード、パスワード、カード、カード、パスフレーズシート、プレーンテキストエクスポート)でFLAG_SECUREが設定されます。iOSには同等のフラグはありません。アプリスイッチャーではアプリのサムネイルが非表示になり、デフォルトでは目のアイコンのトグルで値を確認できます。
- 復号化された値は、画面に表示されている間だけメモリ上に保持され、画面が消えるかアプリがロックされると破棄されます。データキーはリクエストごとに展開され、ロック期間中はキャッシュされません。
- プレーンテキストのエクスポート機能も存在し(いつでも終了できます)、確認シートと新しい生体認証が必要で、その画面もFLAG_SECUREです。
6. 自動入力:何が入力され、何が入力されないか
| どこ | パスワード | カード |
|---|---|---|
| iOS:Safariとアプリ(自動入力拡張機能) | パスワードはい、拡張機能(LAContext)で新しい Face ID / Touch ID / パスコードを取得した後、エントリが保存された登録可能なドメインのみ、Apple のアプリの関連ドメインチェックで有効になります。 | カードいいえ。Safariのカード自動入力機能はApple独自の機能です。カード画面には「AssuredAuthブラウザでコピーして入力」と表示され、それ以外の機能は一切提供されません。 |
| Android: アプリと Chrome (自動入力サービス) | パスワードはい、データセットごとの認証です。システムは入力前にBiometricPromptを表示します。アプリパッケージは、Digital Asset Linksが保存されたドメインにリンクした場合にのみ一致します。 | カードはい、クレジットカード番号、クレジットカード有効期限*、クレジットカードセキュリティコードのヒント、同じ生体認証ゲート |
| AssuredAuthブラウザ(両プラットフォーム対応) | パスワードはい、登録可能なドメインによって、完全に一致するものがないホストが、入力前に生体認証を行うフレームに入力されます。 | カードはい、フィールド検出により、記入前に生体認証を行います。 |
| コピーボタン | パスワードアプリロックの裏側にある、30秒クリップボード | カード番号、有効期限、CVC(同じルール) |
見た目が似ているホストでは何も埋まらない。生体認証なしでは何も埋まらない。
7. 決して起こらないこと
保管庫サーバーなし。保管庫フィールドを含む分析機能なし。確認シートと最新の生体認証情報なしでのプレーンテキストエクスポートなし。保管庫画面にサードパーティ製SDKをロードしない。保管庫画面のスクリーンショットなし。パスフレーズのヒントなし。どのビルドでも値のログ記録なし。
8. 私たちが防ぐことのできないもの
推測されやすいパスフレーズ。ルートレベルでオペレーティングシステムが侵害されている電話(脱獄またはルート化されたデバイスは、上記のすべてについてアプリに嘘をつくことができる)。入力中に監視されている人。貼り付け先のデスクトップにあるマルウェア。このように述べるのは、上記のリストが本来の意味、つまり設計によって削除できるものが削除されたものとして読まれるようにするためです。
9. レビュー状況
この設計は、両プラットフォームで公開されている既知の解答と、独自のクロスプラットフォームベクトルに対して単体テストを実施済みです。保管庫をストアに掲載する前に、所有者は外部レビューを受ける予定です。レビューが実施されるまでは、このドキュメントにその旨を記載します。
10. 各処理が動く場所
保管庫内のデータはスマートフォンから外部に持ち出されることはありませんが、その周辺の一部の機能は他のユーザーの端末上で動作します。以下にその一覧と各機能の内容を示します。データフローの詳細については、https://assuredauth.com/privacy のプライバシーポリシーをご覧ください。
- Google Cloud / Firebase — デスクトップ拡張機能(エンドツーエンドで暗号化されたエンベロープ、既読時に削除)、プッシュトークン、購入ステータス、および問い合わせフォームから送信されたメッセージの中継メールボックス。
- Vercel ― assuredauth.com、そのページ、そしてそれらを支える細かな機能。
- Vultrは、プライベート接続の出口サーバーです。トラフィックはVultrを経由しますが、何も保存されません。
- AppleとGoogle Play ― それぞれのストアでの購入とサブスクリプション。
- PostHog — 製品分析:使用された製品の数を計測し、個人情報とは一切紐づけません。
- RevenueCat — サブスクリプションの状態:有効か期限切れか、およびどのプランに加入しているか。
各商品には、それぞれのラインナップに記載されている内容のみが掲載されており、過去の商品は一切掲載されていません。商品が変更されるとリストも変更され、このセクションもそれに合わせて更新されます。
脆弱性の報告
ここに記載されている内容に脆弱性を発見したと思われる場合は、件名を「セキュリティ」としてhello@assuredauth.comまでご連絡ください。プラットフォーム、アプリのバージョン、手順を明記してください。ご自身のデータを使用した証拠で十分です。他の方のデータでテストすることはご遠慮ください。PGPキーは提供しておりません。平文のメールで報告を送信したくない場合は、最初のメッセージでその旨をお伝えいただければ、別の送信方法をご案内いたします。
弊社がお約束すること:3営業日以内にご連絡いたします。作業中は随時状況をお知らせし、公開前に事実関係を修正いたします。ご希望があれば、こちらにクレジットを記載いたします。下記の範囲内で誠意をもって行われた調査については、法的措置は取らかねます。
対象範囲:iOSおよびAndroidアプリ、ウォッチアプリ、デスクトップ拡張機能、assuredauth.comおよびそのAPI。対象外:App StoreおよびGoogle Play自体、上記に挙げたプロバイダー、あらゆる人物に対するソーシャルエンジニアリング、およびサービス拒否攻撃。
現時点では報奨金はありません。報告に対しては、修正と感謝の言葉で対応し、金銭的な報酬は提供しません。