inSmartBank

B/43を運営する株式会社スマートバンクのメンバーによるブログです

3Dセキュア入門 -B/43の3Dセキュア開発・運用の裏側-

こんにちは。チャージ式プリペイドカードと家計簿アプリがセットになったサービス、B/43のサーバサイド開発をしている@ohbaryeです。

はじめに

唐突な問ですが、読者諸兄はECサイトでカード決済を行う際に本人認証を求められたことはあるでしょうか?弊社のようなカード会社のブログを読まれる方であれば人生で一度は経験しているのではないかと推察します。

この仕組みは3Dセキュアと呼ばれる本人認証サービスで、カードの盗用やなりすましなどの不正利用の防止を目的としてつくられたものです。近年では不正利用防止だけでなく消費者の利便性向上に寄与するシーンも増え*1、B/43にも多くのユーザーさんから3Dセキュア対応の要望がありました。B/43はその要望にお応えして2022年の6月に3Dセキュアに対応したカードをリリースしました

本記事では筆者が3Dセキュアの開発・運用を通じて学んだ、3Dセキュアの仕組み・歴史・技術仕様を主にカード会社の視点から紹介していきます。

※ 本記事はKaigi on Rails 2022にて『Balance Security and Usability in the Field of 3D Secure』と題して発表したセッションの内容の一部を書き起こして再編したものです*2。また、本記事中に現れる画像や文献の出典も以下のスライドの末尾に記載しております。

この記事を通じて学べること

カード事業に携わることがなければおそらく知ることがないであろう3Dセキュアの仕組み・歴史・技術仕様の一端に触れることができます。

また、3Dセキュア自体に馴染みのある方は多くないと思いますが、そこで活用される技術はWeb開発者にとって馴染み深いネットワークやセキュリティの応用ですので、本記事を通じてカード決済や3Dセキュアは異世界ではなく日常のWeb開発と地続きの世界であることを実感いただけると思います。

具体的には以下のような方々を想定読者としております。

  • 認証の応用実例を通じて知識を深めたい方
  • オンライン決済を提供するWebアプリケーションやECサイトに関わる方
  • カード決済/3Dセキュアの裏側の仕組みに興味がある方(非技術者も想定しております)

3Dセキュアとは何か

3Dセキュアとは、端的に言えば、電子商取引に認証を追加することで不正行為を減らすことを目的としたプロトコルです。といってもこの字面だけで実体をイメージするのはほとんどの方にとって難しいと思います。具体的な体験を想起させるため、このように問われたらいかがでしょうか。

おそらくオンラインでのカード決済経験者の99%以上が一度は目にしたことがあるのではないでしょうか。馴染み深いパスワード認証の一種ですね。ユーザー視点で最もよく目に触れる3Dセキュアの実体はこのような認証画面かと思います。

オンラインでのカード決済と課題

このような認証がなぜ必要なのでしょうか。その問に答えるにはオンラインでのカード決済(電子商取引)の基本的な仕組みを理解する必要があります。

オンラインでのカード決済を簡易に表現したのが以下の図です。*3*4*5

  1. カード所有者がECサイトにてカード番号や有効期限を入力し、購入のリクエストを行う
  2. ECサイトがカード会社に利用可否を問い合わせる(この処理を信用照会(オーソリ)と呼ぶ)
  3. カード会社が取引を承認すると決済が成立する

この仕組みには課題があります。もし悪意ある攻撃者が窃取したカード情報を使い、カード所有者になりすまして決済を試みたらどうなるでしょうか。

残念ながら決済は成立してしまいます。この仕組みではリクエストしたクライアントがカード所有者本人であることを誰も確認していないためです。

不正利用を本人認証で防ぐ

この課題を解決するためにオーソリの手前に本人認証を行うようにしたフローが以下です。

カード所有者でしか知り得ないパスワードを要求し、正しいパスワードが入力されればオーソリに進みます。

一方、誤ったパスワードを入力した場合はオーソリに進まずに取引を拒否します。これで不正利用を防ぐことができるというわけです。

認証の応用事例として見るカード決済

ここまでの流れを読んで勘の良い諸氏は「これは認証・認可の仕組みではないか」と気づいたかもしれません。まさにそのとおりで、オンラインのカード決済は3Dセキュアで認証 (authentication) してオーソリで認可 (authorization) する仕組みとなっています。

上記の例では3Dセキュアにおけるパスワード認証を紹介しましたが、オンライン/オフラインそれぞれでカード決済を行うときに用いられる認証は様々です。複数を組み合わせた多要素認証もあります。

  • 知識認証(カード情報、3Dセキュアでのパスワード、PIN)
  • 所有物認証(3DセキュアでのOTP、物理カードの提示)
  • 生体認証(3Dセキュアでの生体認証)

これから皆さんがオンライン/オフラインを問わずカード決済するときに、求められる認証を意識してみると面白いかもしれません*6

3Dセキュア、20年の歩み

さて、ここまでで3Dセキュアが解決したい課題は「オンラインのカード決済における不正利用」 だと説明しました。ここからはどのように解決を試みてきたかの歴史を概説します。

歴史というとやや堅苦しいですが「なぜその技術が生まれたのか」「なぜ現在の形になったのか」といった背景・変遷の理解は技術を理解するうえで重要な手がかりになりますのでお付き合いください。

(2002~) 3Dセキュア1.0時代

3Dセキュアの20年の歴史を振り返るにあたって本記事ではざっくり3つの大きな区分・イベントにフォーカスしてみます。

1つ目が3Dセキュア1.0時代です。3Dセキュアは先述のように「オンラインでのカード取引時の本人認証がない」という穴を塞ぐところからスタートしています。2002年のVisaによるVerified by Visa*7の公開をさきがけとし、各カード国際ブランドも追従する形で3Dセキュア1.0に対応していきました。

ただ、カード国際ブランドが仕様を公開して決済ネットワークが3Dセキュアに対応したからといって、すぐにオンライン取引のすべてで3Dセキュアが発動するわけではありません。3Dセキュアはプロトコルですので、カード決済ネットワークに接続するお店(以下、加盟店といいます)やカード会社のシステム改修が求められます。

また、当時はパスワードによる知識認証しか採用されなかったため、カード所有者それぞれが事前にカード会社にパスワードを登録しなければならないという課題もありました*8。この認証機構自体に馴染みがないユーザーからするとハードルの高いアクションです。

そしてビジネス上もっとも大きな課題がカゴ落ちと呼ばれる、決済するのに必要なステップが増えたことやパスワード入力要求による離脱が発生したことでした。カゴ落ちは加盟店・カード会社・カード国際ブランドの三者にとって避けたい事態ですが、3Dセキュア1.0ではすべての取引においてパスワード認証が求められる仕様だったため、3Dセキュアを導入したためにパスワード忘れや誤入力による取引不成立の割合が上昇する事態にもなりました。

セキュリティ向上のために3Dセキュアを導入したい/するものの、ユーザビリティおよび事業を毀損する可能性がある。3Dセキュア1.0ではセキュリティとユーザビリティ・事業がトレードオフの関係になってしまっていたともいえます。

(2017) 3Dセキュア2.0仕様公開

そのような3Dセキュア1.0の時代が十数年続いたあとの、2つ目の大きなイベントは2017年のEMV Co.*9による3Dセキュア2.0の仕様公開です*10

2.0の仕様は1.0の課題を克服する意図で設計されたためほぼ全ての面で優れています。カード所有者がパスワード忘れや誤入力を起こすかもしれないパスワード認証の代わりにOTPによる所持認証や生体認証が可能になりましたし、モバイルアプリにも比較的スムーズにインテグレートできるようになりました。

リスクベース認証

そんな2.0の仕様でも特筆すべきはリスクベース認証の導入です。すべての取引で本人認証を行うのではなく、カード会社が必要だと判断した場合のみ本人認証を行う仕組みです。

カード会社は取引の情報をベースにリスクを判定し、その結果に応じて以下のように次のステップを決定します。

  • ✅ 低リスク => 本人認証を行わない。オーソリへ進む。
  • ❓ 中リスク => 本人認証を行う。
  • ❌ 高リスク => 本人認証を行わない。取引を失敗させる。

一部のケースでのみ本人認証に進むため多くの取引ではカゴ落ちが発生しません

なお、3Dセキュア2.0では本人認証を要求される体験をチャレンジフローと呼び、本人認証なしで3Dセキュアが終了する体験をフリクションレスフローと呼びます。

「セキュリティを担保するはずの本人認証をスキップする」と聞くとリスクベース認証は大胆すぎるように思えます。しかし、少額決済の大部分は不正ではなく、ユーザーに手間をかけさせるまでもなくオーソリに進んで問題ありません。カード業界の長年の実績と洞察に基づくこの転換により、多くのカード会社や加盟店にとって3Dセキュア導入における一部の課題は解決されました。

(2022) 3Dセキュア1.0廃止

最後、3つ目のイベントは3Dセキュア1.0の廃止です。2022年10月、主要カードブランドが足並みを揃えて3Dセキュア1.0のサポートを終了しました。終了後はすべての3Dセキュア1.0取引はエラーで失敗するようになりました。つい先日の出来事ですね*11

2つのバージョンの併存期間が終わったためこれからはカード会社も加盟店も3Dセキュア2.0にのみ対応していけばよいことになります。


そんなタイミングにて、経済産業省は2022年10月11日にクレジットカード決済システムのセキュリティ対策強化検討会の会合を開催し、国内すべてのEC加盟店に対して3Dセキュア2.0を導入することを義務付ける方針を提言しました。そこでは2025年をめどに全EC加盟店の導入を目指すとされています。

EUではすでにStrong Customer Authentication (SCE)というルールが2019年に施行されており、3Dセキュア対応が要件に含まれています。日本国内での義務化がいつになるかはわかりませんがオンライン決済における3Dセキュア普及の流れは不可逆だと思います。もし本記事の読者にECサイト運営者の方がいましたら、携わるシステムの3Dセキュア対応状況を早急にご確認いただくのが良いかと思います。

3Dセキュアプロトコル入門

ここからは3Dセキュアの技術的な側面を掘り下げてみます。3Dセキュアはプロトコルですので、各社が相互運用できるよう"EMV 3-D Secure Protocol and Core Functions Specification"というドキュメントに技術仕様がまとめられています。*12

しかしながら、3Dセキュアはとても複雑なプロトコルです。同ドキュメントは400ページ超にわたっており、完全に理解するには長い時間を要します。

そのため本記事では入門レベルとして簡略化してアーキテクチャレベルの概説にとどめます。そして、意図的に先送りにしてきたのですが、この節にてようやく「なぜ"3D"なのか?」の問に答えることになります。

登場人物

まずは3Dセキュアを実現するにあたって登場する人物を紹介します。登場するのは人ではなくシステムコンポーネントや事業体であり、人物というと語弊があるため以下ではエンティティと呼称します。

これらのエンティティは3Dセキュアを説明する便宜上、3つのドメインのいずれかの立場に属するものとして分類されます。

Issuer Domain

1つめはカード会社(イシュア)のドメインです。ここには以下3つのエンティティが属します。

  • デバイス
    • カード所有者が利用する端末。Webの場合はJavaScriptやリダイレクト、モバイルアプリの場合はSDKやWebView等により3Dセキュアに関わる通信を行う。
  • Access Control Server
    • リスクを判定し、3Dセキュアにおいてユーザーが体験するフローを決定するサーバー。
  • カード会社 (イシュア)
    • カード所有者にカードを発行する会社。

Acquirer Domain

2つめは加盟店を開拓する会社(アクワイアラ)のドメインです。ここには以下2つのエンティティが属します。

  • 加盟店 (3DS Requestor)
    • ECサイト等。デバイスから購入要求を受け付けた後に3Dセキュアを発動させるか否かは加盟店次第。発動させる役割を持つので3DS Requestorと呼ばれる。
  • 加盟店を開拓・契約する会社 (アクワイアラ)
    • 加盟店を開拓・契約する会社。各カードブランドはカードを使える加盟店を直接開拓しているわけではなく、別の会社に委託するケースがほとんどである。

Interoperability Domain

最後の3つめはIssuerとAcquirerの間で仲介する役割をもつドメインです。ここには以下2つのエンティティが属します。

  • Directory Server
    • 名前の通り辞書の役割を持つサーバー。3Dセキュアが加盟店によってリクエストされたときに、リクエストを転送するAccess Control Serverの情報を持つ。
  • カードブランド
    • VisaやMastercardなど。決済ネットワークの運用に責任を持つ。

実際の通信のようす

登場するエンティティを整理したところで、3Dセキュアプロトコルではこれらがどのように協調して機能するのかを見ていきます。

①デバイスから加盟店に購入リクエストをします。その際に3Dセキュアで必要となる情報が収集されます。ここにはリスク判定の材料となるデバイス情報や位置情報などが含まれます。

②次に加盟店はDirectory ServerにAReq (Authentication Request) と呼ばれるリクエストを投げます。これは「このカード所有者にチャレンジしたい」というリクエストです。Directory Serverはこのリクエストをカード会社のAccess Control Serverに転送します。

③カード会社からはAReqに対する応答、ARes (Authentication Response) を返します。AResには以下のいずれかの結果が含まれ、これにより後続のフローが分岐します。

  • ✅ 低リスク => チャレンジする必要はない。取引額やその他から判断したリスクが低すぎるので、顧客に手間をかけさせなくてよい。
  • ❓ 中リスク => チャレンジしよう。
  • ❌ 高リスク => チャレンジする必要はない。取引を失敗させよう。

本人認証を要求するチャレンジフローも、チャレンジなしで取引が成功/失敗するフリクションレスフローも③までは同じです。

フリクションレスフロー

カード会社の判定結果 (ARes) が低リスク or 高リスクとなりフリクションレスフローに進む場合は以下の流れとなります。

④AResの結果をデバイスに通知します。高リスクであれば取引は成立せず終了します。

⑤~⑥低リスクであれば後続のオーソリに進み、取引が成立します。

裏側では何重も通信が行われていますが、カード所有者からすればECサイトでチェックアウトボタンを押した直後に見るのが取引の結果(成功 or 失敗)となります。

チャレンジフロー

カード会社の判定結果 (ARes) が中リスク、つまりチャレンジフローの場合はさらにやりとりが続きます。

⑤AResを受け取ったのち、デバイスはCReq (Challenge Request)を送信します(「チャレンジを開始しましょう」という意味)。

⑥カード会社は本人確認を求める画面の情報を含むCRes(Challenge Response)を返信します。

⑦~⑧カード所有者が本人確認を終えると、カード会社はその結果をRReq(Result Request)としてDirectory Server経由で加盟店に返送します。

⑨~⑩RReqの結果が成功であれば加盟店は後続のオーソリに進みます。失敗であれば取引を終了します。

ユーザー目線だとチェックアウト後に見えるのはCReq/CResのチャレンジフローのみですが、裏側では3つのドメインのシステムコンポーネント間での複雑なメッセージングが行われています。

なぜ"3D"なのか?

ここまでの説明で察したかもしれませんが、3Dセキュアは3つのDomainが協調して成立するプロトコルであるゆえ、3Dセキュアと命名されています

言葉の由来を説くためにここまでの理解を求められるところが、まさにこのプロトコルの複雑さの一端として表れているように思います。

3DセキュアはWeb技術の総合格闘技

3Dセキュアの技術仕様では上記で述べた内容以外にも数多くの仕様が定められています。その中にはWeb開発をする中で避けて通れないような馴染み深い用語も数多く登場します。各コンポーネント間の通信で使用するHTTPメソッド, Content-Type, Encoding etc.の指定、分散システムにおけるPartial System Outagesの対応、タイムアウト、時刻の扱い等々です。

3Dセキュアの理解にはモバイル含めたフロントエンド、バックエンド、ネットワーク、暗号技術などWeb技術の広い知識が求められるため、Web技術の総合格闘技ともいえます。

興味があればぜひ"EMV 3-D Secure Protocol and Core Functions Specification"を眺めてみてください。

カード会社の3Dセキュア運用

最後にカード会社視点での3Dセキュアの運用の話をします。

3Dセキュアは導入したらそれで終わりではなく、セキュリティとユーザビリティのバランスを上手くとっていけるかどうかはカード会社の運用次第です。なぜなら3Dセキュア2.0において体験を左右するのはリスクベース認証であり、この仕組みは各カード会社のリスクに対する考え方やリスク判定ロジック次第に大きく依存するためです。

リスク判定ロジック

まず、3Dセキュアのリスク判定の具体的な手順を説明します。なお、ここでは手順を単純化しており、全てのカード会社がこのような手順で評価しているわけではない点をおことわりしておきます。

  1. 取引に関する変数からリスクスコアと呼ばれる数字を算出する。
  2. 算出したリスクスコアとしきい値に応じて次のステップを決定する。
# 手順イメージ

# @return [Integer] 1~100
def calculate_risk_score(params)
  # super complicated calculation with params
end

def three_d_secure(params)
  case calculate_risk_score(params)
  in 1...N
    # 低リスク。認証を成功させる
  in N...M
    # 中リスク。チャレンジさせる
  in M..100
    # 高リスク。認証を失敗させる
  end
end

リスクスコア算出

1つの取引のリスクスコアを算出するための変数は数百あります。金額、通貨、カード情報、請求先・配送先住所、デバイス、IPアドレス、加盟店情報、購買データ... 加えて、直近の複数回の取引も考慮に入れることもあります。

また、真に最適化しようとすると加盟店単位でのリスク評価が必要となります。高級時計ECサイトで数十万円の取引は一般的だがフードデリバリーで数十万円の取引は怪しい、というように加盟店によって取引の特徴は異なるためです。

加えて、カード会社によって(正確には提供するカードの商品性によって)許容できるリスクは異なります。富裕層をターゲットにしたブラックカードであれば高額決済が定常的に行われるかもしれません。

しきい値の設定

リスクスコア算出の後はしきい値であるN, Mの設定がセキュリティやユーザビリティを左右します。

# 再掲
case calculate_risk_score(params)
in 1...N
  # 低リスク。認証を成功させる
in N...M
  # 中リスク。チャレンジさせる
in M..100
  # 高リスク。認証を失敗させる
end

たとえばN...Mのレンジを広く設定しすぎると、カード所有者はほとんどの取引でチャレンジを求められてしまい、3Dセキュア1.0のような体験になってしまいます。また、M..100のレンジが広すぎれば、悪意のないカード所有者が行った高額決済が失敗して機会損失となる可能性が増えてしまいます。

少し説明が長くなってしまいましたが、ここまでで適切なリスクスコア算出やしきい値での運用がカード会社に求められることがおわかりいただけたかと思います。

どのような数字をウォッチしているか

最後に、あくまで参考程度ですが弊社がどのような数字を見てウォッチしているかについて一部を公開してみます。こちらも各カード会社の裁量によって見るべき指標や値は大きく変わるため、いずれも正解はないという点に留意ください。


まず、どれだけの金額が3Dセキュアを通じて決済されたのか?を見ています。 不正利用発生時のダメージを鑑みて、一般的に件数よりも金額のほうが重要な指標となります。

2022年9月時点のものですが3Dセキュア未対応の加盟店がまだまだ多いことがうかがえます。


次にリスクベース認証の判定結果です。

国際カードブランドによると約5〜10%がチャレンジフロー、それ以外はフリクションレスフローになるのが目安とされています。実際にB/43におけるオンラインカード決済で本人認証が要求されるのは5〜10%程度となっています。3Dセキュア取引のほとんどが低リスクのため成功(上図のsuccess)となっており、多くのケースではフリクションレスフローでスムーズに取引が完了しているといえます。


最後に、チャレンジフローで提供している認証手段は適切かどうか。

B/43ではSMS・メール・プッシュ通知の3経路をOTPを用いた認証手段として提供しているので、それらの選択率と成功/失敗率を見ています。ここでの失敗は、取引を完了せずに離脱してしまうカゴ落ちの可能性があるため、特定の認証手段の失敗率が高いようであれば表示順を変えたり非表示にする可能性もあります。


この他にもいくつかの指標を見ていますが、いずれも加盟店やユーザーの動向に左右されるものです。運用開始当初から適正値を決めることはできないため、日々監視しつつ適宜調整する、といった柔軟で漸進的な対応が求められました。

このようなプロダクト特性を踏まえての具体的な監視テクニックについてはKaigi on Rails 2021の@ShoheiMitaniの発表がとても参考になるため、興味があればぜひ参照してみてください。

おわりに

本記事では3Dセキュアについて長らく説明してきましたが、いまだ業務を通じて得た知識の10%程度しか公開できていません。1つのプロトコルについて掘り下げるトピックが尽きず、13,000字でも足りないという事実に筆者も驚いています。

最後に、筆者が3Dセキュアについて特に面白いと感じるのは、分散システム上の複雑なプロトコルであるにも関わらず数千数万の企業がこの仕様に従って成立しているという点です。これだけ複雑なプロトコルを普及させた背景には経済的インセンティブ/ペナルティ(チャージバック時の損害補填)や政治的な介入(EUにおけるSCA etc.)等のさらに深堀りできるトピックがあるのですが、本記事の趣旨から逸れるためいずれ別の機会にてお話できればと思います。

本記事はSmartBankで働く@ohbaryeが執筆しました。

SmartBankでは1つのプロトコルを深く掘り下げるのが好きなエンジニアも募集しています。カジュアル面談の応募は以下のリンクからどうぞ!

https://smartbank.co.jp/de1f8d3093a64bcd99e2487352cf5f56

smartbank.co.jp

*1:3Dセキュアに対応しているカードでないと決済できないECサイトや、PayPayのように3Dセキュアで認証すればより便利に使えるサービスが増えています

*2:当日の発表はYouTubeで公開されております。が、30分の動画を見るのもなかなか大変ですね

*3:実際はカード番号をECサイトに送ることはほとんどなく、決済代行会社を経由する

*4:中間には決済代行会社やカードネットワーク等が存在するが簡単のため省略

*5:より詳しい仕組みは『B/43カード決済システムのしくみ(前編)』を参照

*6:余談ですが、情報処理安全確保支援士試験にも3Dセキュアに関する出題がありました。3Dセキュアに関する知識はセキュリティ領域では必須となりつつあるのかもしれません

*7:現Visa Secure

*8:正確に言えば3Dセキュア2.0以降でもパスワード認証を採用している場合は引き続き存在する課題です

*9:カード決済の安全と普及促進する国際団体 https://www.emvco.com/

*10:EMV 3Dセキュアが正式名称ですが本記事では3Dセキュア2.0の呼称を使います

*11:本記事の公開は2022年11月

*12:余談ですが、3DセキュアはIETFによるRFCやISOに依拠する形で設計されています。ドキュメント中に有名なRFCやISOへの言及が多く見つかるので興味があれば覗いてみてください

We create the new normal of easy budgeting, easy banking, and easy living.
In this blog, engineers, product managers, designers, business development, legal, CS, and other members will share their insights.