共通鍵暗号方式の脆弱性とDUKPT

# はじめに
業務で触っているシステムで、機密情報を扱う通信を行う際に、HSMなるものと通信していました。
私はこのHSMがなんたるかを知らなかったのですが、これに関連して以下のような意味の分からない単語が散見されました。

 ・HSM
 ・DUKPT 
 ・BDK 
 ・IPEK
 ・KSN 

ちょっと分からないことだらけで辛かったので、自分なりに調べて分かりやすく嚙み砕いてみました。
もし間違っている箇所があればご指摘いただけますと幸いです。

さて、これらの用語を理解する上では、
どうやら**DUKPT(Delivered Unique Key Per Transaction)** というものをざっくりと理解する方が早そうでした。
このDUKPTですが、どうやら共通鍵暗号方式の脆弱性を軽減ができるようです。
まずはこのDUKPTがどんな場面で必要になるのかを整理し、DUKPTが共通鍵暗号方式の脆弱性をどのように軽減するのかを見ていきたいと思います。

# DUKPTが必要な場面
主に決済系の通信を行う際に使われるようです。
これは自分の推測になりますが、
下記のような理由で、**機密情報を扱う かつ リアルタイム性が求められる場面**でDUKPTが採用されるのだと考えています。

>共通鍵暗号方式は通信速度が速く、リアルタイム性が求められる決済系のシステムと相性が良い
↓
しかし、共通鍵暗号方式には脆弱性がある
↓
>DUKPTはその脆弱性を軽減できる

例：お店でクレジットカード決済を行う場合
お客さんは買い物の度にクレジットカード情報（機密情報）をサーバーに送ってきます。
このとき、毎日ずっと同じ暗号鍵を使っていたら、当然セキュリティリスクは高まります。

では、日ごとに暗号鍵を変えたらどうでしょう？
それでも、1度暗号鍵が盗まれてしまえば、その日に利用されたクレジットカード情報は全て盗まれてしまいます。

では、1時間ごとに・・・

上記のように考え、暗号鍵が盗まれた場合のリスクを最小限にしていき、
**1回の取引（トランザクション）ごとに使う暗号鍵を変えよう**
という発想になったのがDUKPTです。

DUKPTは共通鍵暗号方式をベースにしています。
これはおそらく、公開鍵暗号方式では計算量が多く認証に時間がかかるのと、
秘密鍵・公開鍵をトランザクションごとなどの短いスパンで変更するのは現実的ではないからだと考えられます。

DUKPTがベースとしている共通鍵暗号方式ですが、これには後述のような脆弱性があります。

# 共通鍵暗号方式の脆弱性
共通鍵暗号方式による通信は、以下のような流れで実施されます。
### 共通鍵暗号方式による通信
>①共通鍵Aを用意する。
②なんらかの方法で、各デバイスとサーバーの両方に共通鍵Aを持たせる。
③各デバイスは共通鍵Aを用いて、機密情報を暗号化して送信する。
>④サーバーは共通鍵Aを用いて、暗号化された機密情報を復号する。

### どんな脆弱性があるか

:::note alert
・万が一共通鍵Aが漏れた場合、その後の通信も全て共通鍵Aで暗号化されているため、機密情報が筒抜けになる。
・「なんらかの方法で」共通鍵Aをデバイスとサーバーに持たせる必要があるが、このときに共通鍵Aが漏洩するリスクがある。
:::

# DUKPTの導入
### DUKPTによる脆弱性の軽減
これらの脆弱性を軽減するために導入するのが、
**DUKPT (Delivered Unique Key Per Transaction)**
です。
DUKPTは、共通鍵暗号方式の脆弱性に対して、以下のような方針で対策を行います。

:::note alert
万が一共通鍵Aが漏れた場合、その後の通信も全て共通鍵Aで暗号化されているため、機密情報が筒抜けになる。
:::

トランザクションごとに異なる共通鍵を使い、トランザクション終了後に破棄します。
これにより、**共通鍵が漏れたとしても、以降の通信は別の共通鍵で暗号化されているため、傍受されません。**

:::note alert
「なんらかの方法で」共通鍵Aをデバイスとサーバーに持たせる必要があるが、このときに共通鍵Aが漏洩するリスクがある。
:::

DUKPTでは、デバイス側とサーバー側で共通鍵自体をやりとりすることを避けます。
共通鍵自体をやりとりしない代わりに、トランザクションごとにデバイス側とサーバー側の両方で同じ共通鍵を作ります。
方法は以下の通りです。

①共通鍵を導出するための情報を、予めデバイス側とサーバー側で保持しておく（この情報は通信経路に乗せない）。
②デバイス側は、予めサーバーと共有しておいた情報と、可変の情報（各トランザクションごとに異なる情報）を組み合わせて、共通鍵を作成し、機密情報の暗号化を行う。
③暗号化した機密情報＋共通鍵作成に用いた可変の情報をサーバー側に送る
④サーバー側は、予めデバイスと共有しておいた情報と、送信されてきた可変の情報を組み合わせて、デバイス側で使ったのと同じ共通鍵を作成し、暗号化された機密情報を復号する。

共通鍵自体を通信経路に乗せないため安全性が高まるほか、
**デバイスごとに異なる共通鍵を使用しているため、共通鍵を導出するための情報が漏れたとしても、他デバイスとサーバー間の通信は傍受されません。**

### DUKPT関連の用語
最後に、DUKPT関連の用語を、上記の説明を参照しながら解説します。

**・IPEK (Initial PIN Encryption Key)**
これのこと↓
>共通鍵を導出するための情報を、予めデバイス側とサーバー側で保持しておく（この情報は通信経路に乗せない）

後述するKSNと組み合わせて、トランザクションごとに異なる共通鍵を導出するのに用いる。

**・KSN (Key Serial Number)**
これのこと↓
>可変の情報（各トランザクションごとに異なる情報）

KSNはデバイスID（固定）+トランザクションカウンター（可変）から成る文字列。
トランザクションごとに、トランザクションカウンターの値を変えることで、毎回異なる共通鍵を作成することができる。

**・HSM（Hardware Security Module)**
IPEKや、後述するBDKの発行・保管を行う専用のハードウェア。
ハードウェアといいつつ、この役割を担うソフトウェアがクラウド上にあって、それを指していることもある。

**・BDK(Base Derivation Key)**
IPEKを作成するための大元になる文字列。
絶対に漏らしてはいけないため、**HSMから外には出さない。**
絶対に漏らしてはいけないため、IPEKはデバイス側にも設定するが、BDKはデバイス側にも設定しない。
**絶対に漏らしてはいけない。**

IPEKは、BDKと、KSNのうち固定された部分の情報を組み合わせて作成される。

>サーバー側は、予めデバイスと共有しておいた情報と、送信されてきた可変の情報を組み合わせて、デバイス側で使ったのと同じ共通鍵を作成し、暗号化された機密情報を復号する。

このようなことができるのは、以下の理由のため。
・デバイス側での暗号化に使った鍵は、IPEKとKSNから作成されたものである。
・HSMに保管されているBDKは、KSNの情報の一部からIPEKを作成しているため、暗号化に使ったKSNが分かれば、暗号化に使ったIPEKを導出できる。
・導出したIPEKとKSNから、デバイス側で使った共通鍵を再現できる。

# おわりに
ざっくりとした説明ですが、DUKPTがどんなものなのかは理解できたかと思います。
もしこの記事の内容に瑕疵がありましたら、ご指摘いただけますと幸いです