デジタル署名文脈での公開鍵暗号方式の誤解を避けるため、署名鍵/検証鍵という表現を使うというお話

ritouです。 タイトルに全部書きましたが、Xでharuyamaさんが書かれていたものです。

よくある誤解

最近、公開鍵暗号方式がデジタル署名文脈で使われているユースケースに触れる機会が増えてきました。 自分の守備範囲でいうと

  • OpenID ConnectのIDToken
  • パスキーのAttestation/Assertion
  • 雰囲気で使われているJWT認証()

あたりでしょうか。 もちろん暗号化/復号のユースケースもあるにはあるのですが、自分の観測範囲ではデジタル署名文脈の方が圧倒的に多く使われています。

このあたりを解説しようとする記事において、誤解というか誤った認識をされがちなのが、

  • 送信者はなんらかのデータを暗号化
  • 受信者は復号して…

というものです。

デジタル署名文脈でこの表現をするのを見ると、混乱してそうだなーとなります。

プロトコルでは署名生成、検証とあるのに暗号化とか言ってしまい、さらに尾鰭が付いて送られることのない情報も暗号化によって安全に送れます!なんて主張になると完全な誤りとなってしまうわけです。パスキーでは生体情報などを暗号化して送っているわけではありません。

鍵情報の表現にも利用目的の表現がある

実際プログラムの中だと文脈そんなに気にしなくていいんじゃない?みたいなことを言われたことがありますが、そうでもないです。 JWTの鍵表現で使われるJWKでは、useというパラメータが定義されています。

use (public key use) パラメータは当該公開鍵の用途を示す. use パラメータは, その鍵が暗号化目的で提供されるのか, 署名検証目的で提供されるのかを示すために利用される.

本仕様で定義される値は以下の通りである.

  • sig (signature)
  • enc (encryption) 上記以外の値も利用可能である (MAY).

(さらに使い方を表現するkey_opsパラメータってのもいます)

こういう表現が定義されているほど、この辺りは混ぜるな危険、正しく文脈を理解しましょうということなのです。

署名鍵/検証鍵という表現

プロトコルの理解や、既存システムの理解において、文脈の理解を間違うととんでもないことになることは想像できるでしょう。 冒頭の投稿では、デジタル署名文脈において

  • 署名生成に利用する秘密鍵 = 署名鍵
  • 署名検証に利用する公開鍵 = 検証鍵

というように表現することで、誤用を避けられるのではという主張に見えました。 この表現は確かに文脈の認識がずれにくく、誤解も避けられそうな気がしますね。

自分も公開鍵暗号方式のデジタル署名を利用する仕組みなどを説明したり誤解/誤用を見つけた際はこの表現を利用していこうかと思います。 ID連携の仕様ではprivate_key/public_keyとかが使われているのでそのまま使ってしまいがちですが、共通理解を得るためには柔軟性も必要ですね。

ではまた。

※7/14 追記

この投稿に関して「公開鍵/秘密鍵 という表現をやめることによるデメリット」を指摘する反応が多いように感じました。

  • 秘密鍵を公開しそう
  • 公開鍵を公開していいということがわからなそう

代わりにこういう表現を使おうという主張にしたので、それはごもっともです。 自分の感じている課題はその鍵ペアがあるとなった上で「どのような使われ方をするか」のところが安易に「暗号化/復号」に繋げられてしまうことに課題感を持っているというところなので、秘密鍵/公開鍵それぞれの公開してもいいかみたいなところに影響を与えることは本意ではありません。

というところで、現実的にはデジタル署名文脈での説明においては「秘密鍵/公開鍵は署名鍵/検証鍵として振る舞うのだよ」というような補足をしながら共通認識を持てるようにする、というあたりを意識しています。

署名の文脈で...と言っているので暗号化/復号の話の時に混乱する、みたいな反応も見られましたが、そっちの文脈の定義を崩したいわけではないので話を混ぜないようにしようというのも主張に含まれます。

とにかくまずはパスワードマネージャーを使おう。パスキーは目の前にある。というお話

ritou です。

大きなサービスで何か問題があると、それをきっかけに皆さんのセキュリティ意識が高まりかけたりするものです。 最近はパスワードマネージャーやパスキーについて言及する人も増えてきました。 表題の通り、パスワードマネージャーをお勧めしますという話を書きます。新しい話ではなく、いつもの内容です。

パスワード認証に求められる要件とは?

パスワード認証自体は脆弱な認証方式ではありません。 ユーザー、サービス共に要件を満たして実装、運用されているならば至高の認証方式なのであります。その要件を見てみましょう。

  • ユーザー
    • 推測不可能な文字列にする
    • 複数のサービスで別のパスワードを利用する
    • 忘れない
    • 第3者にパスワードを知らせない
  • サービス
    • パスワードを安全に管理する
    • 各種攻撃からユーザーを保護する

これに対する現状を見てみましょう。

"記憶する" パスワード認証の課題

ユーザー側が記憶で上記の要件を満たそうと思うと、次のような課題があります。

  • ユーザー
    • 推測不可能な文字列にする: 推測しやすい文字列を使ってしまう
    • 複数のサービスで別のパスワードを利用する: 使い回してしまう
    • 忘れない: 忘れてしまう
    • 第3者にパスワードを知らせない: フィッシングサイトを見分けられずにパスワードを入力してしまったり、付箋にメモってみられたりしてしまう

全員が...とは断定はできませんが、ほとんどの人間はパスワード認証の要件を満たせないのであります。

パスワードマネージャーの利用により変わること

世の中のパスワードマネージャーの機能も様々ですが、一般的には次のようになります。

  • ユーザー
    • 推測不可能な文字列にする: 安全な文字列を生成可能
    • 複数のサービスで別のパスワードを利用する: サービスごとにパスワードを保存可能
    • 忘れない: 長期間保存可能
    • 第3者にパスワードを知らせない: アクセスしているドメインなどを利用して、対象のサービスを識別可能

最後のドメイン判定について最近Xで投稿したところ、なぜか反響がありました。

細かい話をすると、このドメイン判定の精度はパスワードマネージャーごとのロジックに依存します。 登録したドメインと一致する場合のみ許容、サブドメインでも許容などいくつかのロジックがあるでしょう。

話を戻すと、要件は大体満たしています。大体、というのは全てをパスワードマネージャーに委ねる利用をしている場合です。

  • パスワードは自分で考える
  • クロスデバイスの場合などに、パスワードマネージャーに表示させたパスワードを目でコピペする
  • フィッシングサイトでも、パスワードマネージャーに表示させたパスワードを目でコピペする

といった使い方をすることで、要件が満たせなくなります。完璧ではない。 しかし、これを言い換えると、この部分が危ないということを知っていたら、気をつけることができるでしょう。

これが まずはパスワードマネージャーを使いましょう という主張をする1つ目の理由です。

パスキー認証との関係は?

次に、パスワードマネージャーを利用するパスワード認証とパスキー認証との関係について整理しましょう。 パスキー認証の最大の特徴である 公開鍵暗号の利用 のおかげで別物として捉えられがちですが、パスキー認証とはパスワードマネージャーを利用するパスワード認証を進化させたもの、強化したものと言えます。ここでは パスワードマネージャーを用いたパスキー認証 についての話となります。

パスワードマネージャーの不完全な点として挙げたものに対して、パスキー認証では次のような特徴があります。

  • パスキー、FIDOクレデンシャルの一番のキモである秘密鍵情報はパスワードマネージャーが生成する
  • どのパスキーを利用するかどうかはサービスが指定したドメイン/オリジンと実際にアクセスしているURLの一致をブラウザが判断した上で認証器に要求が送られる
  • クロスデバイスユースケースを想定してQRコードやPush通知 + BLEを利用した接続したモバイル端末を利用する仕組みがある

パスワードマネージャーで統一されていないドメイン/オリジン判定について、しっかり定義されています。 認証フローにおいて入力されたものがそのまま送られるパスワード認証に対して、パスキー認証では秘密鍵を利用して生成された署名のみがやり取りされるため、フィッシングサイトやクロスデバイスでユーザーの手入力を利用する、というのは仕組みからして困難です。そのため、クロスデバイス用のフローもあらかじめ定義されています。QRコードやPush通知とBLE接続と組み合わせにより、遠隔地にある第3者のモバイル端末を用いた認証を困難とします(近接のデバイスを用いたアレコレはできる余地がありますが一旦割愛します)。

あとは、ここまで触れていなかったサービスがわの要件についても触れます。要件に対して次のような特徴があります。

  • サービス
    • パスワードを安全に管理する: サービスは公開鍵のみ管理するので、漏洩しても不正ログインが困難
    • 各種攻撃からユーザーを保護する: 認証処理における攻撃手法が変わる

管理するのが公開鍵であれば漏洩時の被害が大きく変わるということ、やり取りされるデータがパスワード認証とは異なるために攻撃手法についても変わりますよ、というのは認識しておきましょう。

そして、最近はパスワードマネージャーを用いたパスワード認証からパスキー認証へのアップグレードのための仕組みが出てきています。

android4front.jp

developer.apple.com

この辺りは今後、より使いやすくなるでしょう。

パスワードマネージャーを利用しているユーザーにとって、パスキー認証はもう目の前にあるのです。 サービスがパスキー認証に対応したら、アップグレード機能を利用するなりパスワードマネージャーを使ってシュッとログインした後に設定をすれば良いのです。

これが まずはパスワードマネージャーを使いましょう という主張をする2つ目の理由です。

まとめ

今回は、パスワード認証において記憶のみを利用する場合、パスワードマネージャーを使うことで実現できること、できないこととパスキー認証との関係について整理しました。

触れていない内容として、パスワードマネージャー自体の認証方式とそれへの依拠、知識要素からの変換といった話があります。今回の話でも分かる通り、パスキーで新しく出てきた話ではなく、既にある話なのです。これもXで注目されることが多い話題なので別途整理しましょう。

大事なことなので2回ずつ言います。

まずはパスワードマネージャーを使いましょう。まずはパスワードマネージャーを使いましょう。パスキーは目の前です。パスキーは目の前です。

何かを広めようと思ったら、有識者は同じ話を内容をちょっとずつ更新しながら何度も説明する必要があるでしょう。たまには軌道修正も必要です。 Xでフォローいただいている方にしてみれば「あの猫、またこの話してるんか」というところでしょうが、それが狙いです。

引き続きやっていきましょう。ではまた。

SSF/RISCのユースケースを身近なものとして捉えましょうというお話

ritouです。

「宣伝」2024/05/16(木)にOpenID TechNight vol.21 ~ Shared Signal Framework(SSF)+αの勉強会が開かれるようです。

openid.connpass.com

そもそもSSFって知ってます?勉強会までにSSFについて少し予習しておきましょう。

SSFについて

Tom Satoさんには1月のOpenID Summit Tokyo 2024にてSSFについて講演していただきました。

www.youtube.com

また、昨年末のアドベントカレンダーでも記事を書いていただきました。

zenn.dev

RISCとCAEPをざっくり整理すると、

  • RISC : アカウントに関するイベント送信を送信 (IdPでユーザーが退会した、BANされた、乗っ取られた、メアド変更した時などに連携しているサービスに通知)
  • CAEP : セッションやトークンに関するイベント情報を送信(APIアクセスの環境が変更されたことなどを検知してポリシーに反していたら通知かつ拒否)

として、送られるイベント情報の表現や送受信方法などが何個かのRFCとして策定され、プロファイルの仕様も策定が進められています

openid.net

リソースアクセスにおいても継続的にアクセス評価をしようというCAEPは これまでなかったもの という感じはあるものの、RISCの方はどうでしょう。少し内容をおさらいしてみます。

RISCによるユーザー情報変更時のイベント送信の需要

リスクなんたらというとどうしてもインシデント的なところを思い浮かべてしまうかもしれませんが、ユーザー情報変更時のイベント送信 ぐらいで捉えておくと良いでしょう。

  • ユーザー
  • アプリケーションA
  • アプリケーションB

という登場人物がいて、ユーザーがアプリケーションA/B両方を利用している状態です。 ここでアプリケーションAにてユーザーの属性情報の更新、状態の変更があったときにアプリケーションBに対してイベントを通知する、と言うのが想定されています。

あえてあっさりとしか説明しなかった、アプリケーションA, Bの関係についてID連携と絡めて整理します。

  1. アプリケーションA: IdP, アプリケーションB: RP
  2. アプリケーションA: RP, アプリケーションB: IdP
  3. アプリケーションA, アプリケーションB: どちらもIdP

1は割と想像しやすいでしょう。ID連携で例えばメールアドレスを提供している場合、RP側でそれをどう扱っているかはIdPからそんなにわかりません。 RP側がユーザーのメールアドレス変更に気づくタイミングとして、まずは

  • OIDCのUserInfo Endpointなどを用いてメールアドレスを取得
  • OIDCの認証フローを通してRPにログインするタイミングでIDTokenに含まれるメールアドレスを取得

と言うRP起点のものがあります。

それに対して、IdP起点のものがあります。ユーザー情報の同期みたいなものといえばSCIMが想像できるかと思いますが、RISCは送られるイベント表現という視点から考えた感じとも言えそうです。3rd partyアプリケーションとの連携というよりは、1st partyアプリケーションとの連携などで有用になるかもしれません。

2について、IdPから受け取ったメールアドレスを補完的に利用しつつ、最終的にはRP側でメールアドレスを保持するケースも考えられます。 ID連携でユーザーIDはわかっているので、RPからIdPに「このユーザーはウチでメアド変えたぞ。お前のところでも変更が必要になるかもしれないから一応連絡しとく」みたいな使い方もあり得るかもしれません。

3はIdP同士という少しイメージしずらいところですが、例えばGAFAのような巨大サービス同士であらかじめ「不正利用対策のための情報連携」みたいなものをユーザーに求め、いずれかのアカウントで情報変更があったときに他のサービスにも通知される、というような使われ方が想像できます。

  • Googleでアカウント侵害があり、検知して一時的にアカウントロック
  • Amazon, Microsoftに通知、受け取ったサービスは何かしらの身元確認を要求する

といったような感じですね。ダマでやられるとなんなん?って思っちゃいますが、ユーザーの同意の元でというのはありそうです。

OIDFの説明文でもProvider間みたいな表現がありますね。

The Risk & Incident Sharing and Collaboration (RISC) provides a standardized way to transmit and receive security alerts about such attacks. It enables providers to prevent attackers from compromising linked accounts across multiple providers and coordinate in restoring accounts in the event of compromise.

これは3あたりも見据えているような印象です。 よって、RISCのイベント送信の方向はわりと柔軟に考えられますよ、というのを覚えておきましょう。

認証基盤におけるイベント送信の需要

上の例で結構書いてしまいましたが、いわゆる認証基盤のようなものを提供していると、このような機能を求められることはたまにあります。

  • IdP側でBANや退会してもRPがそのまま使い続けられるのはちょっと困る。RPはログイン時以外にAPIアクセスしてないので、連携ユーザーは退会禁止にしてもらうもしくは退会時にIdPから通知してくれないか?
  • IdP側でアカウント乗っ取りなどが起こった場合、RPはどうしたらええんや。リアルタイム検知とかはどうしたって夢物語なのである程度一緒にやられるのは仕方ないとしても、IdP側で検知したらすぐに教えて欲しい
  • サービス自体が成長した状態からID連携をしたので、ID連携は任意でメールアドレス管理はRPで行なっている。連携状態のユーザーはメールアドレスを同期したい
  • RP「うちはID連携のためのデータストアで、メールアドレスをキーにしている。IdPでメールアドレスを変更したらおかしなことになるので、メールアドレス変更できなくする、もしくは変更後に通知して欲しい」

認証基盤としては特定RPのためのロジックをあまり仕込みたくないものですが、イベント通知であればある程度汎用的に実装できますね。

このように、RISCユースケースは特に新しいものではなく既存の仕組みに存在する要件から来ていると言えるでしょう。 あなたの手がけているサービスや認証基盤でも同じような話、ありませんか?

まとめ

SSFで想定されているRISCについて、このユースケースって結構身近にありそうですよねっていう話を書きました。 認証基盤と呼ばれるものを運用している中であるあるな要件に対応する標準化仕様が考えられているんですよ、ということです。

古い話をすると、元々OAuthだって世の中に存在しない新しい仕組みを考えたわけではなくて既存のサービス(Google, Yahoo! Flickrあたり)が独自で外部サービスへのAPI提供の仕組みを考えて運用していたものをいい感じにまとめようぜ!ってなったものです。

仕様を読んでみて何が定義されているかを理解できてきたら、実サービスへの適用などを考えることでより解像度が上がり、知識として身につくでしょう。自分たちのサービスへの適用を考えたときに「これも欲しい」、「ここもうちょい柔軟にして欲しい」みたいなことが出てきたらコントリビュートのチャンスとなるわけです。

今回はユースケースの話をしましたが、こういうことを考えていると仕様を読んでみたくなりますよね。 どのRFC、どこにどんな仕様が定義されているのかのまとめ記事、JWTの作り方などをZennの方に書こうかなと考えています。

ではまた!

ID連携において重要な "識別子のライフサイクルの考慮" について再考する

ritou です。

ID連携でメールアドレスをキーにするお話

去年はID連携とメールアドレスの関係の話をしました。ちょっとだけ振り返ります。

zenn.dev

この時は、

  • ソーシャルログイン機能を提供するIdP : Googleとか
  • ソーシャルログイン機能を利用するRP : Googleでログインできるサービス

の2サービスのIdentity (not identifier) を email によって紐付けるリスクについて触れました。 仮にある時点において2サービス両方でemailが確認済みだとしても、別のユーザーである可能性がある、という話です。

両方のサービスが頻繁にemail確認をしているならば問題は起こりにくいでしょう。 仮に問題が起こったとしてもカスタマーサポートによる問い合わせ対応でなんとかしようと思えばできますが、サービスの内容によっては問い合わせをするよりも第3者になりすまして悪事を働く方が良いという判断となる可能性もあるわけです。金銭的被害、プライバシー情報の漏洩のように影響が大きくなることが考えられるため、ID連携においてこのような実装パターンはアンチパターンなんですよ。ちゃんと事前に両サービスのユーザー識別子の紐付けを管理しましょうね!というお話でした。

この話題に触れると反応が多いわけですが、現在も記事中の考えと変わりはありません。

前置きが長くなりました。今回は電話番号の話です。

ID連携で電話番号をキーにするお話

LINEにこう言う機能があります。

guide.line.me

企業が保有するお客さまの電話番号を基に、メッセージの送信リクエストをLINEのサーバーへ送信すると、その電話番号が登録されているユーザーのアカウントへLINE通知メッセージが送信されます。

以下の3つの条件を満たすとLINE通知メッセージが配信されます。

  • 企業から送信された電話番号と、同一の電話番号が登録されているLINEアカウントが存在する
  • 当該LINEアカウントが、LINEアプリの設定で「LINE通知メッセージ」の受信を許可している
  • 当該LINEアカウントが配信元企業のLINE公式アカウントをブロックしていない

例えば、荷物の送り先の電話番号を知っている宅配業者のサービスがお届けに関するSMSを送る代わりにLINEのこの機能を通して通知できる というものです。

単なる通知であるとはいえ、これは 宅配業者のサービスとLINEの2者間のIdentity情報を電話番号で紐づける という話とも捉えられるわけです。個人的には、両サービスのIdentityを連携させるわけなのでこれも広義の意味ではID連携と言えると考えています。

これまでの説明の通り、過激派としては初めに某SNSでこれに関する投稿を見たときは当然ながら「これ、意図しないユーザーに通知される可能性はないの?」と思って何回かやり取りしました。

koneta.nifty.com

つまり、「LINE通知メッセージを受け取る」設定がオンになっていて、荷物の送り状に記載された電話番号とLINEの登録番号が一致するユーザーに対して、ヤマト運輸は通知メッセージを送ることができます。

想定したケースは次のようなものです。

1. ある電話番号の所有者がユーザーAからユーザーBに変更(Aが別の電話番号を変更後、Bに再割り当て)
2. ユーザーAはLINEの電話番号を変更していない
3. ユーザーBはLINEに登録していない 

という状況があり得るなら、宅配業者はBに通知を送るつもりがAにいくかも?

自分が気にしているのはユーザーBは現在の電話番号を書いている、そこに宅配業者が通知を送りたい(ここまでに何も問題はない)しかしLINEが挟まることでユーザーAに通知がいく可能性があるのではないかという懸念です。

当然ながらLINEもこのリスクは想定済みであり、最初に載せたページにも電話番号の確認機能があります。

企業からメッセージの配信リクエストを受けた際、LINEに登録された電話番号と使用中の電話番号が一致しているか確認するため、電話番号認証を行う場合があります。

なお、個人情報等を含む通知内容の確認や手続きの継続には、SMSによる本人確認が必要な場合があります。

電話番号の変更、再割り当てといった期間よりも短い間隔でこの確認が入れば、自分の想定にあるユーザーAはもう使っていない電話番号向けの通知を受け取ることはないでしょう。とはいえ、毎度の通知の前にSMSの確認が入るならLINEからのSMSに置き換えられただけじゃねーかみたいなことになるわけなので、それなりに間隔が空いているのかもしれません。その場合は意図せぬユーザーへの通知が行われる可能性が生まれてしまうことになりかねません。

一方で、この通知でできることもある程度のところまでに限定しておくことで、可能性が低いとしても意図せぬユーザーへの通知が行われた際のリスクを軽減できるように設計されていそうです。

電話番号のライフサイクルを考慮して必要な確認を入れつつ、リスク受容もできていると。ここまで考えた上で 事前の連携なしに通知が可能 という機能を提供しているとしたら、私も流石に全否定するつもりはありません。

ヤマト運輸では2016年よりLINE公式アカウントによるサービスを開始しており、当初はヤマト運輸が運営する「クロネコメンバーズ」のクロネコIDとLINEを連携させたユーザーに対して通知メッセージが届くようになっていました。

とある通り、最初は連携させてから通知をおくっていたようですが、きっとあまり使われなかったので電話番号をキーにして事前の連携なしで行けるようにしたんでしょうね。この辺りはあるあるなのでお察しします。

連絡先をキーにするID連携を設計する際の考慮すべきポイント

今回の話と前回のメールアドレスの話を踏まえて、まとめておきましょう。

  • 紐付けのキーとする値のライフサイクルをよく考慮しよう
    • 普遍的でありユーザーに対して一意に割り当てられているユーザーIDであれば意図せぬ紐付けが起こる可能性はほぼない(サービスがよほどやらかさない限り)
    • 電話番号やメールアドレスの再割り当てまでのスパンと各サービス内の確認頻度がずれていると意図せぬユーザーとの紐付けが起こりうる
    • 現在の連絡先の所有者が困った場合のカスタマーサポートなどの問い合わせ経路を用意することも必要だが、ユーザーが自発的にやってくれるかどうかはわからん
  • 意図せぬID連携が行われた際の影響を考慮しよう
    • 「意図せずこの通知を受け取ってしまった場合は無視してください」みたいな程度で済むならサポート対応だけでアリかもしれない
    • ある程度やばいことになりそうならその設計を改めるほうがいい
    • ソーシャルログインのように「あるサービスにログインできる」からの「他者にメッセージが送れる」「そのサービスによって決済機能なども使える」となるとどんどんリスクが大きくなるので、メアドや電話番号をキーにして紐づけるのはアンチパターンだよ(定期)

おまけ

IdPとか認証基盤とかいうのに関わっていると、様々な情報のライフサイクルを考慮することが重要だと感じられる場面が多いです。

  • 電話番号やメールアドレスのような連絡先
  • パスワードやパスキーといった認証のためのクレデンシャル
  • ID連携のアクセストークンやリフレッシュトーク
  • サービス内のユーザー自体
  • サービスを利用するユーザーエンティティ(人間や猫)自体
  • サービス自体

これらのライフサイクルを細かく考慮していくことで、IdPや認証基盤を設計、実装する際に起こりうる脅威やリスクの想定や判断ができるようになる気がします。

IdPや認証基盤の作り方について今度お話しする機会があるので、よかったらオンラインでも聞いてみてください。今回みたいな話もしたいなと考え中です。

ではまた!

macOS向けFirefox(122.0.x)におけるPasskey Autofillの挙動を確認した

こんばんは ritouです。

Firefix の Passkey Autofill 対応

MacOSではFirefox 122.0からiCloud Keychainへの保存と利用が可能になったようです。

www.mozilla.org

Firefox now supports creating and using passkeys stored in the iCloud Keychain on macOS.

ついでに Autofill もサポートしたとか。ブラボー!

早速見てみました。

挙動を確認

この動作確認時の自分の環境のバージョンは

です。

まずは何もパスキーがない状態の挙動を見てみましょう。

Autofillが作動して、なんか出てきました。

iCloud Keychainに保存されていないのでこんなもんか、ここクリックしたらHybrid/SecurityKeyあたりの挙動になるんだろという感じです。

Chrome, SafariQRコードが出てきますが、別の端末のパスキーを使えそうというのがわかったのでおkでしょう。

では1つ登録してみます。

デフォルトだとiCloud Keychainに保存するよとなります。

この状態からAutofillはどうなるでしょうか?

画像撮りなおしたのですが、未登録の時と一緒ですね。サジェストされてこない。

ここで "Passkeyを使用する" を押すとどうなるでしょうか。

iCloud Keychainには保存されているので、出てきます。

なるほどねと。Autofillとは何だったのか という感じになりつつ続けます。

次はもう一個パスキーを登録します。

この時にAutofillの挙動がどうなるかを確認しましょう。

わかってはいましたが、最初の画面は一緒です。"Passkeyを使用する" を押すとどうなるでしょうか。

ここで2つ出てくるわけですね。なるほど。

Autofill使わない、かつユーザー名を入れずに "Authenticate" を押した時と一緒なのでは?と思いました。やってみます。

画像省略です。一緒でした。

まとめ

ということで、現時点のmacOS向けFirefoxのAutofillの挙動 をまとめると

  • Autofill で表示されるのは "Passkeyを使用する" / "パスワードを管理" っていうリンクっていうかボタンだけ
  • 挙動は One Button パターンとか自分が呼んでいたものと一緒

という感じです。

Autofillによって、パスワードの候補と同様のUIとしてパスキーも扱えると思っているとちょっと残念な感じですね。マネフォの人に怒られるぞ

なんとかフォローしようと思うと、MIXI MのようにAutofillのみに対応しているサービスでもパスキーでログインボタンを探しちゃう皆さんにとって、フォームにフォーカス当てるだけでリンクが出てきてわかりやすい人もいるかもしれないぐらいでしょうか?

これが...

こう!

(幅が絶妙で下のログインボタンと一体化してしまったな!)

Windows向けはまた挙動が違うみたいですし、今後改善されることを期待しましょう。

ではまた。

"OpenID Connectは認可のための仕組みであるOAuth 2.0を認証のために拡張したもの" という表現が気になったが実は...

ritouです。

あることがきっかけで、これが気になりました。

この表現、検索するとたくさん出てくるんです。

  • 仕様策定の時期
  • OIDC Core 1.0にある "OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol." という記述の解釈

というあたりからこのような表現になっているのでしょう。

ただ、この前提でプロトコル自体を解説、理解しようとすると何かうまくいかないところがあるのではないでしょうか? と思うところがあります。

特にUserInfo Endpointのあたりについて、

  • これまでOAuth 2.0でプロフィールAPIを実装したら認証に使えたけど実装がバラバラだった(不便なOAuth認証)
  • OIDCではそのレスポンスなどを標準化したんだ!

みたいな説明がされていたりします。何を想像して勝手に経緯を補完しているのだと。 これは言ってしまえばただのOAuth認証の標準化であり、OIDCの方針とは異なります。

ritou.hatenablog.com

実際、このような流れでは仕様策定が行われていないのです。

  • OAuthは利用環境や技術スタックの変化に伴い、リソースアクセスのための仕組みとして1.0 -> WRAP(2.0の初期Draft的な立ち位置) -> 2.0と進化してきた
  • OpenIDも同様の変化を意識しつつ、認証イベントのやり取りのためにOpenID 2.0 -> OpenID Connect と仕様策定が進められてきた
  • 同時期に存在することになったOAuth 1.0とOpenID 2.0を同時に使用するための拡張仕様が策定されたこともあるが、別路線で進んでいた
  • OpenID Connectでは認証イベントのやり取り(IDTokenのあたり)に加え、UserInfo Endpointから非同期/継続的に最新のユーザー情報を取得するという要件があり、この部分が機能的にOAuthと重なる部分である
  • OpenID ConnectのJSON、RESTなどを使うという設計方針と、OAuth WRAPあたりが一致していたため、別々に策定を進めるのではなく「OAuth 2.0の上にIdentityレイヤを乗せる形」として最適化を進めるべく合流した

というのが実際に行われたことです。

この辺りの流れは先日行われたOpenID Summit Tokyo 2024に合わせてNatさんが公開した動画で触れられています。

www.youtube.com

この辺りを意識してもらうと、OIDC/OAuth 2.0のプロトコルを理解しやすくなるかもなーというところでした。

で、心の中で「誰が広めたんや😤」と思っていたわけですが、どうやら自分もその中の一人のようでした。

呪術廻戦 249話 乙骨先輩ばりの展開です。領域展開して踏ん張っていきましょう。この後、退場してしまう気もする

ではまた。

まだはやい 効率的なパスキー管理 - 2023年12月版

ritouです。

この記事はDigital Identity技術勉強会 #iddance Advent Calendar 2023 シリーズ2の記事です。

qiita.com

パスキー管理についてのお話です。

現状

プラットフォーム、OS、ブラウザ、パスワードマネージャーアプリ、アプリケーション全てのレイヤーで一気に対応が進められているパスキーですが、意識を高めて使っていこうと思った時の悩みとして、 どうやってパスキーを管理していくのが安全で便利なんだろう というのがあります。

Apple, Google, MSがパスキーやっていきな声明を出した頃、世の中のほとんどの人がサービス毎に一つだけ パスキーを登録(作成)すればクロスプラットフォームで使えるんや!最高だな!となり、その後の状況を知るとサクッと絶望した人もいるでしょう。世の中そんなものです。

この記事では、よく言われている管理方法と悩みどころについてざっくり整理します。

前提

現状では、パスキーを管理する仕組みとして以下のものがあります。

  • プラットフォームアカウントに紐づけられるパスワードマネージャー: iCloud キーチェーン、Googleパスワードマネージャー(on Android)
  • パスワードマネージャーアプリ: 1Passwordなど
  • セキュリティキー: YubiKey, Titan Security Key

MSも同期がんばれ。と言うことで、まずは、この中でどれを使ったら一番シンプルになるのかなと考える人が多いでしょう。

パスキー管理を一箇所でなんとかできないか

とにかく管理をシンプルにしたい勢の案はこんな感じでしょう。

  • 私はApple端末のみを利用します。別プラットフォームを使うときはiPhoneQRコードを読み込んでなんとかします
  • 私は1Passwordのクロスプラットフォーム対応に賭けます
  • コンシューマー向けサービスでもセキュリティキーを使います

シンプルに管理するということは、単一のパスキーでどこまでいけるか、あとはその管理が第3者に奪われた時にどうするか?が重要になります。 プラットフォームアカウントやパスワードマネージャーアプリのアカウントを⚪︎ぬ気で守る必要がありますし、セキュリティキーで保存できるClient-Discoverable Credentialsには上限がある上に無くしたり壊したりしてはいけない、そしてコンシューマー向けサービスだとセキュリティキー使えないところあるじゃんみたいなところが悩ましいところでしょう。

さいきょうのパスキー管理を目指すぐらい意識が高まっているので、次はその重要なアカウントをパスキーで守ればいいじゃないとなるかもしれません。

一箇所で管理しているパスキーの束をセキュリティキーで守ってみたらどうか

  • AppleGoogleアカウントをセキュリティキーで守るんよ
  • 1Passwordのアカウントもβでなんやかんややってると聞いた

こんな感じで、 パスキー対応サービスのパスキーn個を1個のアカウントに集約し、それをセキュリティキーで守るみたいなやり方がありそうです。

ご存知の通り、Googleアカウントはパスキーとしてセキュリティキーを設定することは、できます。

Appleの場合は2FAですが、セキュリティキーを利用できます。ただし、2個必要でそのうち1個は鍵付きの引き出しにしまっておくんですよ。🐈との約束!

先ほど、こんなこと書きました。

セキュリティキーで保存できるClient-Discoverable Credentialsには上限がある

コンシューマー向けサービスだとセキュリティキー使えないところあるじゃん

いくらTitan Security Keyでたくさん保存できるようになったといえども、普段使いのサービス、これからも増えるとなると保存しきれなくなる気がしますが、重要なアカウントの保護に利用するために使うのは割と適切に見えますね。

これで何となく安全そうですが、

  • プラットフォームアカウント自体のBANとかのリスクもあるよね
  • (これまでの流れを全否定してる気もするが)1箇所で管理するって方法はどうしても利便性悪そう

みたいなところがあります。

となると、単一は諦め、かつそのプラットフォームごとにパスキーがすんなり使えるような状況にしつつ最後にセキュリティキーで守ったらええやんという考えになりそうです。

サービスのパスキーは2箇所とかで冗長化、かつそのアカウントはセキュリティキーで守ってみたらどうか

パスキーを管理するプラットフォームアカウントなんて数が知れているので、そいつらをセキュリティキーで守ってやりつつ、利用しているプラットフォームごとにパスキーは作っておく、どっかのアカウントがおかしくなることも考えてパスキー対応サービスでは2個ぐらいパスキーを登録しておくと言う感じですね。

現状で言うと、安全で便利な感じのパスキー管理としてはこれぐらいかなーと思います。

今後

  • パスワードマネージャーからのエクスポート/インポートができるようになる
  • Windowsでもパスキーが同期できるようになる
  • Googleアカウントに紐付けられたパスキーがPCでも...

みたいなことが進むと、単一のパスキー管理で十分いける状態になるのかもしれません、というかそうなって欲しいですね。

まとめ

何となく想像しているであろうパスキー管理の方法、そして悩みどころを書いてみました。

自分はこう思う、みたいなのがあったらXやはてブで反応いただけるとありがたいです。

2023年12月の時点ではこんなんだったけど、来年末にどうなっているか、楽しみにしながらやっていきましょう。

ではまた。

PWA Night vol.57 ~認証・認可〜 にてパスキーの話をしました

ritou です。

これで話しました。

pwanight.connpass.com

発表資料と発表内容を公開します。

発表資料

speakerdeck.com

発表内容

台本チラ見しながら話したので実際にはこのとおりになってなかった部分もあります。

今日は、パスキーについて話します。

細かい自己紹介は省略します。 色々宣伝したいものがありますがブログに書きます。

今日の内容ですが、初めにパスキーの概要についてざっと触れます。 続いてWebアプリケーションにパスキーを導入するとなった場合にどこから手をつけるべきかというところに触れた後、一番の悩みどころになりそうなログインのUI/UXについて紹介します。

概要からいきましょう。

パスキーの紹介記事もたくさん出ているので要点だけまとめます。

パスキーとは「パスワードが不要な認証方式」であり、それを支える仕様はFIDOアライアンスとW3Cにより策定されています。 最近どこかで見かけた資料にRFCとありましたが、いわゆるWebAuthnはW3Cです。

特徴として、公開鍵暗号による安全性があります。これはネットワークにパスワードのような共有の秘密情報を流さないこと、サービス側は公開鍵のみを保持して漏洩時のリスクを抑えられることがあります。

クレデンシャルの所有者の確認には普段から利用している生体認証などのローカル認証を利用し、パスワードマネージャーによるクレデンシャルの同期機能により、機種変更時や紛失時のリカバリーコストを抑えられるという特徴があります。

サービスからの認証要求に対してブラウザが適切に介入することでフィッシングを検知可能です。 「クレデンシャルを保持している」という所有要素とローカル認証の2要素認証を単体で実現可能なので、パスワード認証の代わりに使えますねというところです。

パスキーの現状として、去年からプラットフォーム、ブラウザの対応が進められました。 具体的にはWebAuthn APIへの対応、パスワードマネージャーへのパスキー保存の部分です。

ある程度動作する環境が整ってきたので、パスキー認証を採用するサービスが増えてきたところが"今"です。 対応サービスが増えると、ユーザーにも馴染みが出てきて、パスキーが使われる状態になるでしょうという流れなのですが、まだまだパスキー対応のプラクティスが十分ではないため、サービスの開発者がまずは先行しているサービスのパスキー認証を利用し、特徴を理解する必要があるでしょう、というのが現状かと思います。

そこでこの本ですね。「まずは使ってみよう。」と。 ここまで話したパスキーの概要についての解説もしているので、是非読んでみてください。

さっきの本を読むと、パスキー対応の意欲が湧いてきます。 ここからはWebアプリというか自サービスに導入するための話をしましょう。

パスワードレスへの道を意識してみましょう。

パスワード認証だけを実装していたサービスは、何らかの攻撃を受けたり、危機意識から2要素認証、2段階認証などを実装しました。 そして、今起きているのは、これまでの認証方式に加えてパスキー認証に対応するというものです。 これができたあと、新規登録時のパスキー登録やパスワード認証の無効化ができると、ようやくパスワードレスが完成します。

しかし、世の中の反応は残酷です。 某Amazonのように、やっとパスキー対応したぞ、となっても「パスワードを無効化できないなら意味ない」みたいな反応がされることもあります。 これはユーザーの期待が現状を超えてしまっている状態だと言えるでしょう。そういえば9月あたりの不正ログインの件はどうなったんでしょうか?

話を戻して、いわゆるパスキー認証への対応としての最低限の実装を紹介します。 それは「パスキーの管理機能」と「パスキー認証を用いたログイン」です。

パスキーの管理機能については、先行して実装したサービスを参考に実装すればある程度迷わずにできるでしょう。

悩みどころとしては、やはりログインのUI/UXのところでしょう。 既存の認証方式に対してどのようにパスキー認証を絡めていくかを考える必要があり、先行して実装したサービスを見ても実装パターンがいくつかあります。

ここからは、ログインUI/UXの実装パターンを紹介します。

まずは Identifier-Firstと呼ばれる実装パターンです。

GoogleAmazonのように、最初にユーザー識別子を入力するパターンです。 これら2つでも細かい違いがあります。

Googleの場合、パスキーの登録状況や環境から、パスキー認証を要求するかどうかを判断します。

Amazonは同様の判断の結果、パスキーでログインするボタンを表示します。あくまでユーザーが選択するもの、という意図なのでしょう。

このIdentifier Firstパターンは、2FAとしてセキュリティキーが利用されていた頃、つまりFIDO認証が始まった当初からあったものと言えます。 「パスワード認証の後にFIDO認証が要求されるフロー」から、パスワード認証が取り除かれてローカル認証が必須になった、と捉えられます。

サービスがパスキー認証を要求するかどうかを判断するわけですが、当然ながら登録されているパスキーがあってもこの環境でそれが利用可能かわかりません。 このため、過去の利用実績を何らかの方法で覚えておいたり、パスキーの登録時の情報と現在の環境を照らし合わせる、などをして判断しているところもあると聞きます。

そして、Amazonのようにユーザーに選択させるところはその分ステップが多くなりますね。

続いて、username lessパターンというものです。

GitHubでは、「Sign in with passkey」というボタンがあり、そこからパスキー認証が始まります。

これは、ユーザー名やメールアドレスといったユーザー情報と一緒にクレデンシャルが保存できるようになった、ResidentKeyやClient Discoverable Credentialといったものが出てきた頃UI/UXです。 セキュリティキーしか使えなかったところから、PCやスマホTPMにクレデンシャルを保存できるようになったあたりですね。

ボタンを押すとこの端末で利用可能なパスキーで認証する、という流れですが、こちらもボタンを押すまで利用可能なパスキーがあるかはわかりません。また、パスキーが登録されていないユーザーも間違って押してしまうかもしれません。この辺りが課題としてあります。

最後に紹介するのが、Passkey AutofillやConditional UIと呼ばれるものを利用するパターンです。

ここで、少し視点を変えてパスキーを考えてみましょう。

パスキー認証は「パスワードマネージャーを利用したパスワード認証」をより進化させた認証方式なのです。 パスワードマネージャーの利用を強制させた上で、「公開鍵暗号方式」と生体認証などの「ローカル認証」を組み合わせたFIDO認証を実現できます。

パスワードマネージャーを利用したパスワード認証では、次の部分がパスワードマネージャーやプラットフォームに依存します。 同一サービスとして扱うかどうかのドメイン判定、パスワード保存時のユーザー名やメールアドレスの扱い、候補として出てきたパスワードを選択した後のユーザーアクションなどです。 また、フィッシング耐性という面では手動のコピペが可能であることが抜け穴となりますし、そもそもサービスはユーザーにパスワードマネージャーの利用を強制できません。

Passkey Autofillではパスワードの時と同様のUXを実現できます。 その上で、対象のドメインやオリジンの値、ユーザー情報をサービスが指定できますし、パスワードのコピペ的なものはありません。

選択後にローカル認証を必要とするかについても、サービスが指定できます。

このPasskey Autofillに対応するサービスも増えてきています。

私が関わっているMIXI Mというサービスは、パスワード認証を利用せずSMS/Email OTPによる認証を採用してきましたが、Passkey Autofillに対応しています。

ユーザー識別子を先に入力するIdentifier FirstパターンのようなUI/UXにもPasskey Autofillを適用可能です。

Passkey Autofillを活用しているサービスとして、マネーフォワード IDがあります。 Identifier Firstパターンを採用しているサービスでは2回Autofillの選択を行う必要があるところも多いですが、 マネーフォワード IDではメールアドレス入力フォームがあり、そこでAutofillの選択を行うとパスワードの場合でもスルッとログインできます。

「パスキーでログイン」というボタンを押させるという新しい体験をさせずに、これまでと同様の体験のままパスキーを利用可能にしているところは現状最も参考になるUI/UXだと言えるでしょう。

まとめです

Auth屋さんの本を買ってパスキー認証の特徴を正しく押さえましょう。

Webアプリケーションへの導入において、最低限の機能は「パスキー管理」と「ログイン」であることを意識しましょう。

ログインのUI/UXは3種類ぐらいに分類できて「Passkey Autofill」がオススメです。

質問など、いつでもお待ちしています。 ありがとうございました。

質問があったら?

Xでこの記事へのリンクをつけつつ聞いてもらえたらと思います。

ではまた。

共有端末におけるパスキー利用可否の解像度を上げる

ritouです。

Xを日々パトロールをしていると、共有/共用端末(これ正式な用語としてはどっちなん?以下、共有と呼びます。)でのパスキー利用について思いを馳せる人が目につくようになりました。

だいたいの人は

共有端末ではパスキーは使えない!完

という認識でしょうけれども、実際どうなんでしょうか?

今回はもうちょっと解像度を上げるための細かい話をしましょう。

共有する範囲

まずは 共有端末と言っても、実は細かく色々あるんじゃないの? というところです。

サービスを利用するにあたって、ユーザーが専有できる範囲はどこなのか、複数ユーザーと共有する範囲はどこなのかというところがいくつかあるでしょう。

  • (A) 端末ごとにユーザーが異なる: 個人PCやモバイル端末を利用
  • (B) 端末のプロファイル(ログインユーザー)が異なる: 会社のPCに社員がログインして利用
  • (C) 端末のプロファイルは一緒、ブラウザのプロファイルが異なる: ユーザーが複数のGoogle Workspaceアカウントを持っており、アカウント毎にChromeのプロファイルをわけて利用
  • (D) 端末、ブラウザプロファイルまで一緒: 家族で使うなんとかかんとか

(A), (B)あたりは個人端末扱いと言えるでしょう。(D)もわりと直感的です。 (C)は他人とというよりも個人で複数アカウントという感じかもしれませんが、Google視点では別人ですよね。なので、このあたりから共有端末と呼んでも良いのではと思います。

この記事ではここまでの整理にして、その先の利用者の多様性(家族、ネットカフェのユーザー、会社の訪問者、市役所の訪問者)みたいなところは考慮しません。

パスキーが使えるかどうか の判断においては、この共有範囲に対してパスキーの管理方法が一致するかによって決まります。

Authenticatorの種類

これはだいたいイメージできているものだと思います。

  • (1) プラットフォームアカウントに同期されたパスワードマネージャー : iCloud Keychain, Google Password Manager
  • (2) 端末のプロファイルごとに管理: ちょっと前までのTPMに保存されるやつ
  • (3) 外部のパスワードマネージャー: 1Password
  • (4) ブラウザプロファイル単位で管理: (2)よりもうちょい細かく管理されたやつ。MacOSChrome
  • (5) セキュリティキー: Yubikey
  • (6) 手元のモバイル端末で管理: Hybrid Transportでモバイル端末を利用

この(A)-(D)と(1)-(6)について、組み合わせで考えていけば良いのです。

共有範囲に対して利用可能なAuthenticatorの種類

猫に表にしましょう。

共有範囲 利用可能なAuthenticatorの種類
(A) (1), (2), (3), (4), (5)
(B) (1), (2), (3), (4), (5)
(C) (4), (5), (6)
(D) (5), (6)

こんな感じで、共有する範囲が広がるほどに利用可能なAuthenticatorの選択肢が限られてくるわけです。

ということで、(D)のように同一ブラウザプロファイルでユーザー認証が必要なケースの場合、

  • セキュリティキーを配布して利用
  • Hybridで手元のモバイル端末を利用

あたりのUXやパスキー管理自体で運用可能かどうかを判断する必要があります。

エンタープライズ領域のようにセキュリティキーの管理が可能なケースだったら良いでしょうし、Hybridの方はスマホアプリ+モバイルアプリでパスキーを生成しつつ店頭の端末でパスキーを利用みたいなこともあるかもしれません。

まとめ

細かく考えると 共有端末におけるパスキー利用はAuthenticatorの種類が制限されるものの不可能ではないかもしれない というお話でした。

きっかけ

今回の記事のきっかけはこちらのニュースです。

www.asahi.com

県病院局によると、看護師は2018年1月~今年1月、勤務時間中に同僚医師の電子カルテのパスワードを使い、アトピー治療用の軟膏(なんこう)や飲み薬の処方箋を計22回不正発行した。

県は電子カルテに2段階認証を導入するなど、再発防止を進めるとしている。

操作したのはブラウザではなく専用ソフトとかなんでしょうけども、こういうケースは(D)の環境と言えるでしょう。

コンビニのレジのようにバーコードで識別するぐらいの要件ならまだしも、

有印公文書偽造・同行使の疑いで県警に刑事告発

みたいなことになるぐらいの要件であれば、セキュリティキーを用いたFIDO認証を実装してみたらどうかなと思いました。

ではまた。

え? OAuth 2.0 の Access Token も JWT じゃなかったの?と思っている皆さん

こんばんは、ritou です。

パスキーの記事ばっかり書いてないでたまにはOAuthのことも取り上げましょう。

OAuthのAccess Tokenについて少し復習してみましょう。

OAuthのAccess Token ってJWTじゃないの?

これについては、我らが Auth屋さん がお話しする会みたいなので自分の方でもいくつか勝手に質問に答えた中にありました。

www.rfc-editor.org

1.4. Access Token

Access tokens are credentials used to access protected resources. An access token is a string representing an authorization issued to the client. The string is usually opaque to the client. Tokens represent specific scopes and durations of access, granted by the resource owner, and enforced by the resource server and authorization server.

と言うように、ここでは opaque = 不透明?ぐらいしか定義されていません。

www.rfc-editor.org

This specification defines a profile for issuing OAuth 2.0 access tokens in JSON Web Token (JWT) format. Authorization servers and resource servers from different vendors can leverage this profile to issue and consume access tokens in an interoperable manner.

JWTのフォーマットを決めたらRSとASが異なるサービスの場合でも互換性取りやすいと言うところです。

Access Tokenの設計については、素晴らしい解説記事があります。

qiita.com

JWTかどうかわからないならClientはデコードできないのでは?

ClientはOAuthのAccess Tokenをデコードする必要はありません。

この思い込みはどこから来るのでしょうか?

いわゆる OAuth認証 においてリスクを回避するためにアクセストークンの発行対象が正しいかどうかを検証すべきみたいな話がありました。そのために、Clientはアクセストークンが自分に対して発行されたものであることを確認できるべき、JWTなら署名検証してPayloadを見たら確認できるじゃんと言うところから来ているのではないかと思っています。

OAuthにおける各種トークンのAudienceとは誰でしょうか?

  • Authorization Code: Token Endpoint
  • Refresh Token: Token Endpoint
  • Access Token: Protected Resources

となります。素晴らしい解説動画があります。

www.youtube.com

Clientはこのトークンを使ってRSにアクセスしろ、と言うだけの話なので中身を知る必要はありません。 上記のように、ClientがATの中身を気にする必要があるケースは、何かしら設計が間違っている可能性があります

ちなみに、OIDCのIDTokenはClient(RP)ですよ。

最後に

JWT な Access Token と言えばこの人ですね。

RFC 9068 の Author

R.I.P.