Credential Exchange Protocol(CXP)は、パスキーやパスワードをあるパスワードマネージャから別のパスワードマネージャへ、暗号化したまま移すための仕様です。FIDOアライアンスが、データ形式を定めるCredential Exchange Format(CXF)と対で策定しています。2026年9月にはAndroidでこの仕組みを使った転送が始まり、利用者が平文のCSVを書き出さずに乗り換えられるようになりました。本記事では、CXPとCXFの役割分担と策定状況、AndroidとiOSで転送を実装するAPI、そしてパスキーが別のマネージャへ移った後も自社サービスのログインを壊さないためにRP(パスキーを受け付けるサービス側)が確かめる値と画面を、手を動かす順に並べます。パスキー認証そのものの位置づけはパスキー認証とは?仕組み・パスワードとの違い・企業の導入判断を前提にしています。
まとめ:CXPとCXFの策定状況とRP側で先に確かめる値と画面
結論を先に書きます。2026年10月時点で、データ形式のCXFは1.0のProposed Standardまで進み、転送手順のCXPは2024年10月のWorking Draftのままです。AndroidとiOSが公式ドキュメントで準拠先として示しているのはデータ形式の側で、転送は同じ端末の上でOSが仲介します。端末をまたぐ移行や、iPhoneとAndroidの間での移行は、まだ標準の経路がありません。
RPの実装は原則として変える必要がない。CXFはcredentialId・rpId・userHandleを移行先へそのまま渡すため、サーバに保存した公開鍵で署名の検証が通り続けます。
見直しが要るのは周辺です。登録時のAAGUIDから「Googleパスワードマネージャーで作成」のような表示を出している画面、認証器の種類で登録を絞る許可リスト、そして登録状態をマネージャへ伝えるSignal APIの呼び出しの3か所を確認してください。自社でパスワードマネージャや認証アプリを提供しているなら、エクスポートとインポートの実装が乗り換えられる側の条件になります。
Credential Exchange Protocolの定義とCXFとの分担・策定状況
CXPとCXFは、片方だけでは移行が成立しない組み合わせです。中身の形を決めるのがCXF、その中身を安全に運ぶ手順を決めるのがCXPと分かれています。
CXPが定める転送手順:ImporterとExporterとHPKEによる暗号化の流れ
CXPのWorking Draft(2024年10月3日付)では、受け取る側をImporter、渡す側をExporterと呼びます。移行を始めるのは受け取る側で、ImporterがExportRequestを作り、暗号化に使う公開鍵と受け取りたい資格情報の種類を指定します。
利用者が移行元で承認すると、Exporterは資格情報をまとめて暗号化し、ExportResponseとして返します。暗号化にはRFC 9180のHPKE(Hybrid Public Key Encryption)を使い、モードはbase・psk・auth・auth-pskの4種類から選ぶ設計です。ペイロードはzip形式のアーカイブで、中のファイルを1つずつJWEで暗号化します。
応答の返し方はdirect・indirect・selfの3種類があります。directはOSやExporterが受け渡しの経路を用意する場合、indirectはファイルとして書き出す場合、selfは同じ事業者の中でのバックアップに使う場合です。移行が済んだ後に移行元から資格情報を消す処理はスコープ外と明記されています。FIDO2の規格群の中での位置はFIDO認証・FIDO2とは?仕組みとパスキー・導入判断を解説で整理しました。
CXFのデータ構造とHeader・Account・Item・Passkeyの必須項目
CXF 1.0(正誤表反映版・2026年3月9日付)は、移行するデータをHeader・Account・Collection・Item・Credentialの階層で表します。Headerの必須項目はversion・exporterRpId・エクスポート元の表示名・timestamp・accountsで、versionはmajorが1、minorが0です。エクスポート元の表示名に対応する正確なフィールド名は、直下のJSON例に記載しています。
パスキーはtypeが”passkey”のCredentialで、credentialId・rpId・username・userDisplayName・userHandle・keyの6項目を必ず持ちます。keyは秘密鍵をPKCS#8のASN.1 DERで表し、base64urlで符号化した値です。最小構成の例を示します(値は説明用のダミー)。
{
"version": { "major": 1, "minor": 0 },
"exporterRpId": "exporter.example.com",
"exporterDisplayName": "Example Password Manager",
"timestamp": 1791158400,
"accounts": [{
"id": "QWNjb3VudElk",
"username": "taro.yamada",
"email": "taro.yamada (example.com)",
"collections": [],
"items": [{
"id": "SXRlbUlk",
"title": "Example Shop",
"credentials": [{
"type": "passkey",
"credentialId": "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA",
"rpId": "shop.example.com",
"username": "taro.yamada",
"userDisplayName": "Taro Yamada",
"userHandle": "M2YPl-KGnA8",
"key": "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg"
}]
}]
}]
}
emailの値は、配信時にメールアドレスとして自動変換されるのを避けるため書式を崩しています。実データでは通常のアドレスが入ります。注意したいのは参照する版です。CXFはWorking DraftからProposed Standardまでの間に項目の定義が動いており、古いドラフトを基にした解説やパーサは項目名や必須の範囲が食い違うことがあります。実装の基準は正誤表反映版に置き、項目名は”username”のように1文字単位で突き合わせてください。
2026年10月時点のCXFとCXPの策定段階の違いと実装着手の判断
FIDOアライアンスのダウンロードページに2026年10月時点で載っているのは、CXF 1.0のProposed Standardとその正誤表、そしてCXP 1.0のWorking Draftの3点です。CXFは2025年3月のReview Draft、同年8月14日のProposed Standardを経て、2026年3月に正誤表が出ました。
CXPはWorking Draftの冒頭で、実装の土台にすることを意図していないと断っています。実装要件を書く章も空のままです。したがって、自社でCXPのHPKE交換をそのまま実装する判断は、2026年10月時点では早いと考えます。手を付けるなら、仕様が固まっているCXFの読み書きからです。
AndroidとiOSで資格情報の転送を実装するAPIとコード例
ここからは、パスワードマネージャや認証アプリを提供する側の作業です。両OSとも、アプリ同士を直接つながず、OSが間に入って受け渡します。
AndroidのCredentials Transfer APIによる受信側の実装手順
Androidの公式ドキュメント(2026年10月1日更新)によると、Credentials Transfer APIは同じ端末上のプロバイダ同士で資格情報を移すAPIで、準拠先はFIDOのCXFです。Android 8(API 26)以上で動き、依存ライブラリは androidx.credentials:providerevents の1.0.0-alpha06系です。alpha版なので、版を固定して追随してください。
受け取る側は、受け取りたい種類を指定して importCredentials() を呼ぶだけです。OSが移行元の選択画面を出し、完了するまで処理を止めます。
suspend fun startImport(activity: Context, manager: ProviderEventsManager) {
val request = ImportCredentialsRequest(
credentialTypes = setOf(
CredentialTypes.CREDENTIAL_TYPE_BASIC_AUTH,
CredentialTypes.CREDENTIAL_TYPE_PUBLIC_KEY
),
knownExtensions = setOf(KnownExtensions.KNOWN_EXTENSION_SHARED)
)
try {
val response = manager.importCredentials(activity, request)
val exporter = response.callingAppInfo.packageName
val cxfJson = response.response.responseJson
saveImported(exporter, JSONObject(cxfJson))
} catch (e: ImportCredentialsException) {
handleImportFailure(e)
}
}
CREDENTIAL_TYPE_PUBLIC_KEYの値はCXFのtypeと同じ”passkey”で、受け取るJSONは先の例と同じ構造になります。データはBinderの1MB上限を避けるため、一時的なキャッシュファイルを背後に持つContent URIで受け渡されます。
Exporter側の実装で守る呼び出し元検証とcredIdのノンス照合
渡す側は、まず registerExport() でExportEntryを登録しておきます。登録していないプロバイダは移行元の候補に出ません。サインアウトした時点で clearExport() を呼び、候補から外すところまでが実装範囲です。
移行の要求を受けたActivityでは、検証を3段で行うよう公式ドキュメントが求めています。最も強い防御は、登録時に生成して暗号化ストレージに保存したランダム値と、受け取った credId が一致するかの照合です。次に呼び出し元のパッケージがOSの選択画面(Google Play開発者サービスを載せた端末では com.google.android.gms)であるかを確かめ、最後に移行先アプリの情報を画面表示と信頼判断に使います。
サンプルコードには、呼び出し元の判定が常にtrueを返す仮の実装が含まれています。そのまま本番へ持ち込むと、検証が1段抜けた状態で出荷されます。生体認証を挟んでから秘密鍵を書き出す流れも、公式の例どおりに入れてください。
iOS 26で資格情報を転送するAPIとInfo.plistの宣言項目
iOS 26で資格情報の転送に使うApple側のAPIはAuthenticationServicesのASCredentialExportManagerで、iOS・iPadOS・macOS・visionOSの26.0以上が対象です。資格情報プロバイダ拡張のInfo.plistで、ASCredentialProviderExtensionCapabilitiesの下にSupportsCredentialExchangeをYESで置き、SupportedCredentialExchangeVersionsに対応するデータ形式の版を並べます。2026年10月時点で指定できる版は1.0だけです。
渡す側は requestExport(for:) で移行を始め、返ってきたExportOptionsの版に合わせてデータを組み、exportCredentials(_:) に渡します。受け取る側は、OSから起動されたときに importCredentials(token:) を呼ぶ流れです。Appleのドキュメントは、この過程でファイルシステムへ何も書き込まないと明記しています。
AndroidとiOSで、移行の途中にファイルを経由するかどうかが異なる点は押さえておきたい。どちらも利用者の手元に平文が残らない設計ですが、端末内の一時領域を監査する場合は確認の観点が変わります。
パスキーが移った後もログインを壊さないためのRP側の確認作業
自社サービスがパスキーを受け付けているなら、利用者のパスキーはある日、別のマネージャへ移っているかもしれません。RPの側では気づかないまま移るため、壊れやすい箇所を事前に洗っておきます。
移行後のcredentialId・rpId・userHandleとサーバの検証条件
CXFのパスキーは、credentialId・rpId・userHandle・秘密鍵をそのまま運びます。移行先のマネージャは同じ秘密鍵で署名し、同じcredentialIdを名乗るため、サーバに保存した公開鍵とcredentialIdの組で検証は通ります。RPがCXPのために新しいエンドポイントを用意する必要はありません。
逆に言えば、サーバ側で変えてはいけない値がはっきりします。rpIdを途中で変えたり、userHandleを再採番したりすると、移行の有無に関係なくパスキーが使えなくなります。登録と認証でサーバが検証する項目の全体はWebAuthnとは?パスキー認証を実装する仕組みと登録・認証フロー・RP実装の要点で扱いました。
もう1点、W3C WebAuthn Level 3(2026年8月25日に勧告)は、バックアップ可否を示すBEフラグを資格情報ごとに恒久の性質と定義し、バックアップ状態を示すBSフラグは時間とともに変わりうるとしています。移行の前後でBSが変わっても、それだけで不正と判定するロジックは誤検知を生みます。
AAGUIDでプロバイダ名を表示している画面と認証器の許可リストの見直し
見落としやすいのが、登録時に受け取ったAAGUID(認証器の種類を示す識別子)を保存し、アカウント設定画面に「iCloudキーチェーンで作成」のような名前を出している実装です。パスキーが別のマネージャへ移っても保存済みのAAGUIDは更新されないため、画面の表示だけが実態とずれます。
対処は2通りあります。表示を「作成時のプロバイダ」と明示して事実として正しい文言に直すか、表示自体をやめて作成日と最終利用日だけを出すかです。サポート窓口への問い合わせを減らしたいなら、後者のほうが割り切れる。
AAGUIDや構成証明で登録できる認証器を絞っている業務システムは、もう一段の検討が要ります。許可リストは登録時点の検査なので、登録後に秘密鍵が別のマネージャへ移ることは止められません。端末やセッションへの結び付けで補う考え方はDBSCの標準化動向とパスキー連携で整理しています。
signalAllAcceptedCredentialsで移行先へ登録状態を同期する実装
移行先のマネージャは、RP側で既に削除されたパスキーまで受け取っている可能性があります。WebAuthn Level 3の§5.1.10に定義されたSignal Methodsを使うと、サーバが有効と認めるcredentialIdの一覧をログイン後にマネージャへ伝えられます。
if (PublicKeyCredential.signalAllAcceptedCredentials) {
await PublicKeyCredential.signalAllAcceptedCredentials({
rpId: "shop.example.com",
userId: userHandleBase64url,
allAcceptedCredentialIds: acceptedIdsBase64url
});
}
userIdとallAcceptedCredentialIdsはbase64urlの文字列で渡します。一覧に無いパスキーをマネージャが非表示にするかどうかは実装依存で、呼べば必ず消えるわけではありません。ブラウザごとの対応状況と、パスワード併存からの移行全体の手順はパスキー移行の実装手順:パスワード併存からSignal API・CXPでの鍵移行までにまとめました。
CXPへの対応を急ぐ条件と見送る場面・企業の管理端末での運用判断
立場をはっきりさせます。RPとしては「壊さない確認」だけを今すぐ行い、CXPそのものの実装は資格情報を保管する製品を持つ会社だけが着手すればよい、というのが2026年10月時点の判断です。
自社でパスワードマネージャや認証アプリを持つ場合は対応を先に進める
資格情報を保管するアプリを提供しているなら、インポートの実装は優先度を上げてください。Googleの公式ブログ(2026年9月10日)によれば、対応済みはGoogle Password Manager・1Password・Bitwarden Password Manager・Dashlaneの4つで、他社もAPIに対応すれば加われます。乗り換え先の候補に出ないことは、そのまま新規利用者の取りこぼしになる。
エクスポートは逆に、急がない選択もあり得ます。ただし利用者を囲い込むために出口を塞ぐ設計は、パスキーの普及を進める各OSの方針と向きが逆です。中長期では、エクスポートに対応していないこと自体が選ばれない理由になると見ています。
管理端末で社用パスキーの持ち出しを止めたい場合に確認する設定
社用のパスキーを個人のマネージャへ移されたくない組織は、仕組みの前提を押さえておくと判断が早い。Androidでは移行元として候補に出るのはExportEntryを登録したプロバイダだけで、移行のたびに移行元アプリでの承認が要ります。つまり、止められるかどうかは導入しているパスワードマネージャの側の設定と実装で決まります。
確認の順番は、業務で使うマネージャの管理コンソールにエクスポートの制限項目があるか、次に従業員の個人マネージャへの保存を規程で禁じているか、の2点です。パスワードを含む資格情報の社内ルールの決め方はパスワード管理のベストプラクティスを土台にしてください。
反対に、移行の可否を気にするあまり同期型のパスキーそのものを禁止するのは過剰です。秘密鍵を外へ出さない物理セキュリティキーはCXFのkeyを埋められず移行の対象外なので、持ち出しを確実に止めたい特権アカウントだけをそちらへ寄せる設計で足ります。
外部の手を借りる境界:認証基盤の改修と移行テストをどこまで委ねるか
自社で進めやすいのは、AAGUIDを使った表示の洗い出しと、rpIdやuserHandleを変える予定がないかの確認までです。コードを検索すれば対象がほぼ特定できます。
手間がかかるのは、許可リストや構成証明で認証器を絞っている業務システムの方針の見直しと、Signal APIの組み込みを含む認証基盤の改修、そして複数のマネージャで移行後のログインを通す試験です。認証の方式設計から改修と試験までを一括で外へ出すなら、認証基盤・ID管理システム開発のような形で、守るアカウントの範囲と許容する認証器の種類を先に決めてから依頼すると無駄が少ない。
よくある質問
CXPとパスキーの移行について、検討段階で出やすい質問に答えます。
iPhoneとAndroidの間でパスキーを移せますか?
2026年10月時点では、標準の経路はありません。AndroidのCredentials Transfer APIは同じ端末の上でのプロバイダ同士の転送で、AppleのASCredentialExportManagerも同じ端末のアプリ同士で受け渡す仕組みです。OSをまたぐ移行は、両方のOSで動くパスワードマネージャを経由するのが現実的です。端末やOSをまたいで直接運ぶ手順はCXPが担う領域ですが、その仕様はまだWorking Draftの段階にあります。
従来のCSVエクスポートとは何が違いますか?
最大の違いは、移行の途中で平文が利用者の手元に残らないことです。CSVは書き出した時点でパスワードが読める状態のファイルになり、消し忘れや誤送信の危険がありました。CXFに沿った転送では、OSが移行元と移行先の間に入り、AppleはファイルシステムにCSVのような痕跡を書かないと説明しています。加えて、CSVでは運べなかったパスキーの秘密鍵を移せるようになりました。
移行した後、元のマネージャのパスキーは消えますか?
自動では消えません。CXPのWorking Draftは、移行後に移行元から資格情報を消す処理をスコープ外と明記しています。結果として、移行後は同じcredentialIdのパスキーが2つのマネージャに並んで存在する状態です。どちらで署名しても同じ秘密鍵なのでログインはできますが、不要になった側は利用者が手で削除します。RP側でパスキーを削除した場合の同期は、Signal APIで補う形になります。
RP側でCXPに対応するための実装は必要ですか?
認証そのものの実装は不要です。移行先のマネージャは同じcredentialIdと秘密鍵で署名するため、サーバの検証はそのまま通ります。手を入れるとすれば、登録時のAAGUIDから作成元の名前を表示している画面、認証器の許可リスト、Signal APIの呼び出しの3か所です。rpIdとuserHandleを変えないことも、移行に耐えるための前提になります。
物理セキュリティキーのパスキーも移せますか?
移せません。CXFはパスキーの秘密鍵をPKCS#8の形式でkey項目に入れることを求めており、秘密鍵を外へ出さない設計の認証器はこの項目を埋められないためです。移行の対象は、パスワードマネージャやOSが同期している型のパスキーに限られます。持ち出しを確実に防ぎたいアカウントは、この性質を逆手に取って物理キーへ寄せる選択肢があります。
関連記事
- パスキー認証とは?仕組み・パスワードとの違い・企業の導入判断を解説:パスキー認証の位置づけと導入判断を扱っています。
- FIDO認証・FIDO2とは?仕組みとパスキー・導入判断を解説:CXPを含むFIDOの規格群の全体像を確認できます。
- WebAuthnとは?パスキー認証を実装する仕組みと登録・認証フロー・RP実装の要点:RPが実装する登録と認証の検証項目を解説しています。
- パスキー移行の実装手順:パスワード併存からSignal API・CXPでの鍵移行まで:パスワードからパスキーへの移行手順を扱っています。
- パスワード管理のベストプラクティス:NIST SP 800-63B-4の要件と総務省・NISCの推奨、企業ポリシーの決め方:資格情報の社内ルールの決め方をまとめています。