WebAuthnがパスキー認証で非対称暗号化アルゴリズムとpubKeyCredParamsをどのように使用するか、またcredentialPublicKey、CBOR、COSEの役割について解説します。
Vincent
Created: August 8, 2025
Updated: August 8, 2025
See the original blog version in English here.
Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.
デジタルセキュリティの世界では、パスキーがパスワードレス認証の新しい標準となっています。パスキーの中核をなすのが公開鍵暗号技術です。これはパスキーの基盤であるWebAuthnプロトコル内で利用されています。パスキー認証を設計したり利用したりする上で、WebAuthnで公開鍵暗号がどのように使われているか、特にパスキーの作成、抽出、管理、保存においてどう機能するかを理解することは非常に重要です。公開鍵は証明書利用者(RP)のサーバーに保存されます。RPとは、パスキーでユーザーを認証したいウェブサイトのバックエンドのことです。一方、秘密鍵はオペレーティングシステムに応じて、ハードウェアセキュリティモジュール内に安全に保管されます。例えば、Secure Enclave(iOS)、TEE(Android)、TPM(Windows)などです。
この記事では、パスキーで使われる公開鍵暗号の基本を簡単に見ていきます。この記事を読み終える頃には、以下の疑問が解消されているはずです。
WebAuthnにおける公開鍵暗号の仕組みを理解するために、まずはその一般的な仕組みと、よく使われるアルゴリズムの種類を簡単に見ていきましょう。
公開鍵暗号は非対称暗号とも呼ばれ、暗号化と復号に同じ鍵を使う対称暗号とは対照的です。非対称暗号では、公開してもよい公開鍵と、所有者が秘密にしておく秘密鍵という2つの異なる鍵を使います。
出典: https://en.wikipedia.org/wiki/Public-key_cryptography
この方式では、データの機密性を保護するための暗号化だけでなく、メッセージへの署名も可能です。署名によって送信者の身元が検証され、メッセージが改ざんされていないことが保証されます。これにより、メッセージの真正性と完全性が確認できるのです。
公開鍵暗号で使われる一般的なアルゴリズムの種類をいくつか紹介します。
カテゴリ | RSA | DSA | ECDSA | EdDSA |
---|---|---|---|---|
発明年 | 1977 | 1991 | 1999 | 2011 |
アルゴリズムの種類 | 非対称公開鍵暗号 | デジタル署名アルゴリズム | 楕円曲線デジタル署名 | エドワーズ曲線デジタル署名 |
主な用途 | 安全なデータ伝送 | 電子文書への署名 | 安全なトランザクションと署名 | 安全なトランザクションと署名 |
一般的な鍵長 | 1024~15360ビット | 1024~3072ビット | 160~512ビット | 256ビット |
パフォーマンス | 鍵長が大きいため低速 | 署名はRSAより高速 | 短い鍵で高速な計算 | 速度とセキュリティに最適化 |
普及度 | 歴史的に広く使用 | RSAより一般的でない | 人気上昇中 | 急速に人気が拡大 |
モバイルデバイスでの効率 | モバイルでは非効率 | 中程度の効率 | モバイルデバイスで高効率 | 最高の効率 |
鍵のストレージ要件 | 鍵長が大きいため要件大 | 中程度 | 少ないストレージ容量で済む | 最小限のストレージで済む |
バッテリー消費 | 消費量が多い | 中程度の消費量 | 低消費電力 | バッテリー維持に最適 |
モバイルへの適合性 | サイズと電力のため不向き | 中程度の適合性 | 非常に適している | 非常に適している |
標準規格での採用 | 広く採用 (TLS, SSH) | あまり広く採用されていない | 現代的なプロトコルで広く採用 (TLS, SSH) | 新しいプロトコルで採用が拡大 (TLS, SSH) |
将来の脅威への耐性 | 量子攻撃に脆弱 | 量子攻撃に脆弱 | 量子攻撃に耐性を持つ可能性 | 量子攻撃に耐性を持つ可能性 |
汎用性 | プラットフォーム間で高い汎用性 | 特定のユースケースに限定 | 高い汎用性 | 高い汎用性 |
特許の状況 | 特許なし | 特許なし | 特許なし | 特許なし |
ECDSAやEdDSAを含む楕円曲線暗号(ECC)の数学的基盤には、楕円曲線の特性が関わっていますが、この記事では触れません。しかし、上の表から明らかなように、その採用を後押しする利点があります。次のセクションでは、その中でも特に重要な点を見ていきます。
楕円曲線暗号は、その鍵長の短さからモバイルデバイスで広く採用されており、次のような利点があります。
セキュリティレベル(ビット) | RSA鍵長(ビット) | ECDSA/EdDSA鍵長(ビット) |
---|---|---|
80 | 1024 | 160-223 |
112 | 2048 | 224-255 |
128 | 3072 | 256-383 |
256 | 15360 | 512+ |
ここでのセキュリティレベルという用語は、暗号システムの強度、具体的には攻撃者がセキュリティ対策を破ることの難しさのレベルを指します。一般的にビット単位で測定され、暗号を破ったり署名を偽造したりするのに必要な作業量(操作の数)を表します。セキュリティレベルが上がるにつれて、鍵長の比率が1:30に達するまで、サイズの利点は明らかになります。
アルゴリズム | 鍵長 | 署名操作 | 署名/秒 |
---|---|---|---|
RSA | 2048 | 0.001012s | 987 |
ECDSA | 256 | 0.000046s | 21565 (x20) |
これらの要因により、ECCはストレージ、処理速度、消費電力の最適化が不可欠なモバイル環境に特に適しています。その結果、ECCはデバイスのパフォーマンスを損なうことなく堅牢なセキュリティを提供できるため、モバイルコンピューティングでますます好まれるようになっています。それにもかかわらず、今日に至るまで、HTTPS、FTPS、SMTPSなどで使用されるTLSや、SSH、IPsecといった普及しているプロトコルの古いバージョンの多くは、依然としてRSAをサポートしていますが、ECCをサポートするクライアント向けにECCベースのバリアントも提供し始めています。
WebAuthn標準は暗号化の標準ではなく、強力な公開鍵ベースの認証をウェブアプリケーションに提供するセキュリティプロトコルです。これにより、ユーザーはパスワードの代わりに生体認証、モバイルデバイス、またはハードウェアセキュリティキー(例:YubiKeys)を使ってログインできます。そのため、WebAuthnは基盤となる公開鍵暗号の種類を意図的に問いません。これがどのように実現されているかを見てみましょう。
WebAuthnセキュリティプロトコルは、ユーザーと**証明書利用者(Relying Party)**との間の暗号学的に安全な認証を促進します。技術的に言えば、これは証明書利用者(ユーザーにパスキーを使わせたいウェブサイト)が、ブラウザを介してユーザーとその認証器と鍵を交換する必要があることを意味します。認証器は、特定のハードウェアセキュリティモジュール(HSM)に秘密鍵を保存します。
パスキーのサインアップ/登録には、3つの重要なステップがあります:
PublicKeyCredentialCreationOptions
と共に、PublicKeyCredentialCreationOptions.pubKeyCredParams
を介してサポートする暗号化アルゴリズムを通知します。pubKeyCredParams
リストをチェックし、自身がサポートする暗号化アルゴリズムを探して、一意のCredential IDと共に鍵ペアを作成します。秘密鍵をHSM内に保存し、公開鍵と使用された暗号化アルゴリズムをブラウザに返します。その後、ブラウザは「authData」セクションにattestationObjectを含めて、証明書利用者のバックエンドにPOSTリクエストを送信します。サポートされている暗号化アルゴリズムが一致しない場合、作成処理は失敗します。attestationObject
を受け取ります。authData.credentialPublicKey
セクションを解析し、公開鍵を抽出します。公開鍵と共に、使用された暗号化アルゴリズムとCredential IDに関する情報も証明書利用者に送り返されます。その後のパスキーによるログイン/認証には、以下のステップが必要です(詳細は簡略化しています):
両方のケースを見ると、パスキーのサインアップ/登録時にのみ、公開鍵と暗号化アルゴリズムの情報が関係者間でやり取りされることがわかります。
その後のパスキーによるログイン/認証イベントでは、チャレンジと署名のみが送信データの一部となります。
WebAuthn標準では、使用される暗号化アルゴリズムを識別するためにIANA COSEアルゴリズムIDを使用します。COSEアルゴリズムIDは、pubKeyCredParamsでサポートされるアルゴリズムを通知するためと、実際に作成された鍵ペアのタイプをcredentialPublicKeyで送信するための両方で使用されます。 次の2つのセクションでは、これらの実装に焦点を当てます。
IANAのCOSEアルゴリズムリストには75以上のアルゴリズムが含まれており、理論的にはWebAuthn標準で使用できます。負のIDを持つアルゴリズムのほとんどは非対称公開鍵で、正のIDのほとんどは対称鍵ですが、これには例外もあるため、どちらかというと慣例です。
前述の通り、暗号化アルゴリズムは、WebAuthnの処理で使用されるために、認証器と証明書利用者の両方のバックエンドでサポートされている必要があります。ほとんどの証明書利用者は、幅広い暗号化アルゴリズムにアクセスできる既存のWebAuthnライブラリを使用しているため、どのアルゴリズムがどの認証器でサポートされているかを見ることの方が重要です。
名称 | ID | 説明 | Apple | Android | Windows 10 | Windows 11+ | セキュリティキー |
---|---|---|---|---|---|---|---|
RS256 | -257 | SHA-256を使用したRSASSA-PKCS1-v1_5 | ❌ | ❌ | ✅ | ✅ | ✅ |
EdDSA | -8 | EdDSA | ❌ | ❌ | ❌ | ❌ | ✅ (*) |
ES256 | -7 | SHA-256を使用したECDSA(NIST P-256としても知られる) | ✅ | ✅ | ❌ | ✅ | ✅ |
(*)=一部のセキュリティキー(例:Yubikeys 5+、Solokey、Nitrokey)
IANAテーブルからの抜粋:完全なリストはこちら
この表からわかるように、すべての主要な認証器をサポートするには、RS256とES256で十分です。コミュニティの一部では、セキュリティをさらに向上させるためにEdDSAも統合することを推奨しています。一方で、保存する必要のあるCredential IDは、EdDSAキーの方が著しく長いようです。今日現在、次期レベル3 WebAuthn標準に関するW3C編集者草案では、3つすべてのアルゴリズムが提案されています。
パスキー作成でサポートされる暗号化アルゴリズムの設定は、PublicKeyCredentialCreationOptions
を介して行われます。
const publicKeyCredentialCreationOptions = { challenge: "*", rp: { name: "Corbado", id: "corbado.com", }, user: { id: "user-X", name: "user@corbado.com", displayName: "Corbado Name", }, pubKeyCredParams: [ { alg: -8, type: "public-key", }, { alg: -7, type: "public-key", }, { alg: -257, type: "public-key", }, ], authenticatorSelection: { authenticatorAttachment: "platform", requireResidentKey: true, }, }; const credential = await navigator.credentials.create({ publicKey: publicKeyCredentialCreationOptions, });
この例は、アルゴリズムがpubKeyCredParams内で、IDを表すalg
とアルゴリズムのタイプとしてpublic-key
を追加することで指定される方法を示しています。29/30行目で、PublicKeyCredentialCreationOptionsがブラウザのWebAuthn APIを介して認証器に渡されます。ES256またはRS256のサポートを削除するとエラーが発生するため、絶対に推奨されません。
動作例として、MacのPasskeys Debuggerで次のPublicKeyCredentialCreationOptions
を実行してみます。
{ "rp": { "id": "www.passkeys-debugger.io", "name": "Relying Party Name" }, "challenge": "AAABeB78HrIemh1jTdJICr_3QG_RMOhp", "pubKeyCredParams": [ { "type": "public-key", "alg": -8 }, { "type": "public-key", "alg": -7 }, { "type": "public-key", "alg": -257 } ], "excludeCredentials": [], "timeout": 120000, "authenticatorSelection": { "residentKey": "required", "requireResidentKey": true, "userVerification": "required", "authenticatorAttachment": "platform" }, "hints": [], "attestation": "direct", "user": { "name": "User-2024-08-19", "displayName": "User-2024-08-19", "id": "LlakhOS2vobxxwdkInYP-277Atf0S5OsJax_uBCNNINk" } }
認証器によって生成されたレスポンスは、証明書利用者(アテステーションとして)に送信され、次のようになります。
{ "id": "aWMmE4BE9ZzvRKd9rQhdy6ubrlB3COrTRFQANe6ydHg", "rawId": "aWMmE4BE9ZzvRKd9rQhdy6ubrlB3COrTRFQANe6ydHg", "type": "public-key", "response": { "attestationObject": "o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIhAIvVNCTlYXX7WKOfeto7WyBQE6uvXpvnNy22kqrMxs_QAiAmanFqalrvD_1fe0Cb2f60ljth4nngckkKJ8JPtqZiO2hhdXRoRGF0YVikt8DGRTBfls-BhOH2QC404lvdhe_t2_NkvM0nQWEEADdFAAAAAK3OAAI1vMYKZIsLJfHwVQMAIGljJhOARPWc70Snfa0IXcurm65Qdwjq00RUADXusnR4pQECAyYgASFYIDP4onRKVHXlhwbmWF4V6jmfsuVuSXchGm6xoceSBGtjIlgg3bxZIbKyE7qPczMZmS0jCGBf9cgajs77EZL-gNAjO0c", "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQUFBQmVCNzhIckllbWgxalRkSklDcl8zUUdfUk1PaHAiLCJvcmlnaW4iOiJodHRwczovL29wb3Rvbm5pZWUuZ2l0aHViLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ", "transports": ["internal"], "publicKeyAlgorithm": -7 }, "authenticatorAttachment": "platform", "clientExtensionResults": {} }
次のセクションでは、このレスポンスから公開鍵と使用された暗号化アルゴリズムを抽出する方法を見ていきます。
まず、実際のattestationObject
がどのように構築されているかを調べる必要があります。なぜなら、上記のようにJSON形式で証明書利用者に転送されるわけではないからです。
attestationObjectはWebAuthnの登録プロセスで重要な役割を果たし、認証器が提供するアテステーションステートメントのコンテナとして機能します。このオブジェクトは、証明書利用者(RP)が新しく作成された公開鍵クレデンシャルの出所と完全性を検証するために必要な多くの情報を提供します。
その核心において、attestationObjectは複雑な構造をしています。ほとんどがCBOR(Concise Binary Object Representation)形式でエンコードされ、最終的にBase64URLエンコーディングでエンコードされます。これには、認証器データと、情報の真正性を検証するアテステーションステートメントがカプセル化されています。パスキーはアテステーション「none」で作成され、アテステーションステートメントを持たないため、この記事ではこれについては触れません。補足として、オプションの拡張機能に必要な可変長のため、非標準のCBORプレフィックスも関わってくるため、ほとんどCBORと書きました。これ以上深くは掘り下げませんが、その複雑さについての議論はこちらで見つけることができます。
WebAuthn仕様書より引用
認証器データ(authData)内には、新しく生成された公開鍵がユーザーのクレデンシャルIDと共に安全に保存されており、証明書利用者が取得できます。開発者は、WebAuthnベースのシステムでattestationObjectから公開鍵を抽出する作業に取り組む必要があるため、そのアーキテクチャを理解することが重要です。
CBOR(Concise Binary Object Representation)は、データをコンパクトで効率的、かつ拡張可能な方法でエンコードするために設計されたデータ形式です。バイナリ形式であるため、テキストベースのモデルであるJSONよりも小さく、解析も高速です。以下の例は、JSONとCBORの違い(テキスト vs. バイナリ)を示しています。
JSONテキスト | CBORバイナリデータ | CBORデコード結果 |
---|---|---|
Name:Corbado | A1 64 4E 61 6D 65 67 43 6F 72 62 61 64 6F | A1 # map(1) with one entry 64 # text(4) 4E616D65 # Name; 67 # text(7) 436F726261646F # Corbado |
太字はName。 斜体はCorbado。(詳細はhttps://cbor.io/を参照)
WebAuthnの文脈では、CBORはいくつかの理由で使用されます。
CBORの使用は、公開鍵とattestationObjectのエンコードに特に適しています。なぜなら、前述したさまざまなフォーマットと長さを処理する必要があるからです。例えば、RSAキーはECDSAキーとは異なる属性とサイズを持ちます。attestationObject内では、公開鍵はCBORベースのCOSEキーフォーマットで保存されます。
COSEキー構造は、CBORマップオブジェクト上に構築されています。これは、RSAモジュラスや指数、または楕円曲線の公開鍵座標など、さまざまなキータイプとそれに対応するパラメータを含む、キー表現の構造化された方法を定義します。この標準化されたフォーマットにより、前述の暗号化アルゴリズムIDに加えて、基盤となる暗号アルゴリズムに関係なく、キーを一貫した方法でシリアライズおよびデシリアライズできます。
CBORとCOSEキーフォーマットを活用することで、WebAuthnは幅広い暗号操作を促進しつつ、ペイロードを可能な限り小さく保ち、将来の暗号技術の更新にも適応できるようにします。この選択は、安全で効率的、かつ将来性のあるウェブ認証プロトコルを提供するというWebAuthnの目標と一致しています。
WebAuthn内でattestationObjectをデコードする際、開発者は重要な決断に直面します。カスタムソリューションを開発するか、確立されたライブラリを活用するかです。このプロセスの複雑さと重要性は、いくら強調してもしすぎることはありません。Base64URLとCBORのデコードを手動で実装することは技術的には可能ですが、認証プロセスの完全性を損なう可能性のある微妙なエラーを招くリスクがあります。
署名の暗号学的検証、および他のすべての検証ステップの正確性を保証するために、十分にテストされ、広く採用されているWebAuthnライブラリを利用することを強く推奨します。このようなライブラリは、attestationObjectのデコードと検証の詳細を処理するための暗号化の専門知識を持って構築されています。これには以下が含まれます。
信頼できるライブラリに頼ることで、開発者は時間とリソースを節約するだけでなく、安心感も得られます。これらの信頼できるツールを通じて抽出・検証された公開鍵は、データベースに安全に保存され、安全な認証セッションで使用できるようになります。このアプローチにより、プロトコルの仕様への準拠が保証され、WebAuthn実装に期待されるセキュリティ体制が維持されます。簡単にするため、ここではSimpleWebauthn Debuggerを使用します。これは、CBORフィールドが展開されたJSONに変換された、完全にデコードされたバージョンを返します。
{ "id": "aWMmE4BE9ZzvRKd9rQhdy6ubrlB3COrTRFQANe6ydHg", "rawId": "aWMmE4BE9ZzvRKd9rQhdy6ubrlB3COrTRFQANe6ydHg", "type": "public-key", "response": { "attestationObject": { "fmt": "packed", "attStmt": { "alg": "ES256 (-7)", "sig": "MEUCIQCL1TQk5WF1-1ijn3raO1sgUBOrr16b5zcttpKqzMbP0AIgJmpxampa7w_9X3tAm9n-tJY7YeJ54HJJCifCT7amYjs" }, "authData": { "rpIdHash": "t8DGRTBfls-BhOH2QC404lvdhe_t2_NkvM0nQWEEADc", "flags": { "userPresent": true, "userVerified": true, "backupEligible": false, "backupStatus": false, "attestedData": true, "extensionData": false }, "counter": 0, "aaguid": "adce0002-35bc-c60a-648b-0b25f1f05503", "credentialID": "aWMmE4BE9ZzvRKd9rQhdy6ubrlB3COrTRFQANe6ydHg", "credentialPublicKey": "pQECAyYgASFYIDP4onRKVHXlhwbmWF4V6jmfsuVuSXchGm6xoceSBGtjIlgg3bxZIbKyE7qPczMZmS0jCGBf9cgajs77EZL-gNAjO0c", "parsedCredentialPublicKey": { "keyType": "EC2 (2)", "algorithm": "ES256 (-7)", "curve": 1, "x": "M_iidEpUdeWHBuZYXhXqOZ-y5W5JdyEabrGhx5IEa2M", "y": "3bxZIbKyE7qPczMZmS0jCGBf9cgajs77EZL-gNAjO0c" } } }, "clientDataJSON": { "type": "webauthn.create", "challenge": "AAABeB78HrIemh1jTdJICr_3QG_RMOhp", "origin": "https://opotonniee.github.io", "crossOrigin": false }, "transports": ["internal"], "publicKeyAlgorithm": -7 }, "authenticatorAttachment": "platform", "clientExtensionResults": {} }
SimpleWebAuthnライブラリは、完全なattestationObjectをデコードするために使用されます。ご覧の通り、すべての情報が読み取り可能になりました。すべての暗号情報はauthDataの一部であるcredentialPublicKeyに含まれており、ライブラリはこれをparsedCredentialPublicKeyステートメントに展開しています。仕様書には、COSEキーフォーマットがどのように見えるかの例がいくつかあります。
{ "parsedCredentialPublicKey": { "keyType": "EC2 (2)", "algorithm": "ES256 (-7)", "curve": 1, "x": "M_iidEpUdeWHBuZYXhXqOZ-y5W5JdyEabrGhx5IEa2M", "y": "3bxZIbKyE7qPczMZmS0jCGBf9cgajs77EZL-gNAjO0c" } }
この出力は、credentialPublicKeyのすべての暗号要素が、人間が読める形式にきれいに解析されていることを示しています。この特定のインスタンスは、アルゴリズムパラメータとxおよびy座標の存在によって示されるように、ES256アルゴリズム用のEC2キーを明らかにしています。
対照的に、Windows 10システムの出力は次のようになります。
{ "parsedCredentialPublicKey": { "keyType": "RSA (3)", "algorithm": "RS256 (-257)", "modulus": "mzRVwAL6jbccWT4NQ3rQWEYLkTKkEBeHPPUn0CXT8VwvvGE_IaXDeP9ZzcA7WoX3z6E0l_L-XZmRuKc9cO7BkiYyz3jOg_pNFTz5Ap9a1f_9H0m4mpL-30WHQZi1skB5f6zt8sO8q7rBYH0mRmH8LdCrhJRhVjB_UxbcAbYlpV98M5g-5OBs_boNXtMhMoyp-IOeGChp07wwSLVOH3hKMoxlU27hZ3QvK2LRWosNKhXSHcU9IOC0XOyhlZ5rtPX2ae3KsSE1H2rEJVcMaVMRAg8yx2SRM98pDvf829smrnJPdMBojKftne2j8o84i_xyDJ_jARlyVj0kxR37u0AVQQ", "exponent": 65537 } }
ここでは、アルゴリズムIDは-257で、RS256に対応しており、この公開鍵を特徴付ける属性がECDSAキーのそれとは大きく異なることがわかります。COSEキーフォーマットでは、タイプごとに固有の属性を指定できます。
属性/タイプ | ECDSA | RSA |
---|---|---|
キータイプ | EC2 (Elliptic Curve 2) | RSA (3) |
アルゴリズム | ES256 (-7) | RS256 (-257) |
固有の属性 | 曲線 X座標 Y座標 | モジュラス 指数 |
また、RSAモジュラスはES256キーで使用される楕円曲線座標よりも大幅に長く、これは鍵サイズの違いと異なる暗号アルゴリズムの固有の要件に関する以前の議論を裏付けています。
公開鍵暗号の基本を学び、それがWebAuthn / FIDO2標準にどのように組み込まれているかを理解した上で、証明書利用者に対する2つの主要な推奨事項があります。
車輪の再発明をしないことが重要です: 確立されたライブラリに組み込まれた集合知を活用しましょう。カスタム実装は、認証の有効性とシステム全体のセキュリティを損なう可能性のあるエラーやセキュリティ上の欠陥を導入するリスクがあります。
この記事では、公開鍵暗号の基本を調査し、冒頭の3つの中心的な質問に答えました。
さらに、WebAuthnプロトコルが特定の暗号化アルゴリズムから独立していることを強調しました。これにより、柔軟性が大幅に向上し、将来登場する暗号化手法に対する備えができます。この記事が、他の開発者がWebAuthnにおける公開鍵暗号に関連する概念や問題をデバッグし、理解する際にも役立つことを願っています。
Enjoyed this read?
🤝 Join our Passkeys Community
Share passkeys implementation tips and get support to free the world from passwords.
🚀 Subscribe to Substack
Get the latest news, strategies, and insights about passkeys sent straight to your inbox.
Related Articles
Table of Contents