RSAのパディング：PKCS#1 v1.5, OAEP, PSSを整理してみた

### はじめに
　基本的なRSA暗号に関する標準規定は当初PKCS #1として制定されましたが、現在ではこの内容はIETFのRFCに引き継がれています。2021年時点での最新であるPKCS #1 V2.2 (RSA Cryptography Specifications Version 2.2)はRFC 8017として定義されていて、暗号、復号、署名と検証の方法（プリミティブとスキーム）などの規定が含まれています。

暗号復号処理では復号ができたからといって、そのメッセージが正しく元のメッセージであるということが保証されるわけではありません。メッセージの真正性を検証するために、メッセージにパディングを付加してから暗号化し、復号時に検証するという手法がとられます。

PKCS#1(RFC8017)には、RSAのためのパディングスキームについても規定されています。当初、PKCS#1 v1.5として比較的単純なスキームが規定されましたが、その後より改善された方式として、暗号復号化には最適非対称暗号パディング(OAEP: Optimal asymmetric encryption padding)、また、RSAを公開鍵署名のために利用する場合のパディングとしては確率的署名スキーム(PSS: Probabilistic signature scheme)が標準化されています。PKCS#1 v1.5も後方互換のために残されていますが、現在はこれらを使用することが推奨されています。

### 1) PKCS#1 v1.5

図にPKCS#1 v1.5とOAEPのパディングスキームを比較します。

![fig3-6-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263939/cc190043-a631-5ceb-9b77-3519e5d4f30b.jpeg)

v1.5のスキームでは、暗号化対象のメッセージに所定の固定のビットパターンとハッシュ関数による擬似乱数で構成されたパディングを付加して、全体をあわせてRSA暗号化プリミティブで暗号化します。このような暗号化を行うと、パディングの擬似乱数値を知らずに固定パターン部分と元のメッセージを捏造することは非常に難しくなります。復号の際は、パディング部分についてもとの固定パターンが正しく復号されていることを確認することで元のメッセージの真正性を判定します。

### 2) OAEP

OAEPでも、暗号化対象のメッセージにパディングを付加します。図においてlHashは使用するハッシュアルゴリズムによって決まる固定値、PSは長さ調整のための値ゼロの列です。OAEPでは、これとは別に適当なSeed値を用意します。暗号化の前に図に示すようにこの値とふたつのハッシュ関数を使ってハッシュ値を求め排他的論理和によるマスクをほどこし、0x00のパディングを付加した結果をRSA暗号化プリミティブで暗号化します。

復号の際はRSA復号化したビット列にたいして最後に付加した0x00が正しく復元されていることを確認します。次にメッセージ部分とパディング部分のビット列からもとのシード部分を復元し、復元したシード値を使ってメッセージ部分を復元します。シード値が正しく復元されていない場合は最終的に復元されるパディング部分に影響するはずです。このようにすることで、復号側でシード値を知らなくてもパディングに単なる固定値を使用するよりはるかに堅牢な暗号化が可能となります。

OAEPや次に説明するPSSで使用されるハッシュ関数にはMGF(Mask Generation Function)と呼ばれるハッシュスキームが使用されます。MGFはSHAなど固定サイズのハッシュ関数をベースに所望のサイズのハッシュを得ることができるようにしたハッシュスキームです。


### 3) PSS

これに対してPSSは署名検証のために開発されたパディングスキームです。PSSでは、適当に選ばれたソルト値を署名のためのハッシュ値に付加した上でそのハッシュ値を求めます。一方、ソルト値にパディングを付加したものに対して、先のハッシュ値とMGFによってマスクし、両者をあわせ固定値0xbcを付加したものを署名値としRSA署名プリミティブを適用します。

![fig3-6-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263939/1aa6733a-acc6-9041-9d7b-c4e34f6d8b9f.jpeg)



検証では、まず固定値0xbcの部分をチェックしRSAプリミティブの処理が正しく行われていることを確認します。その後ハッシュ値をつかってソルト値が復元できるのでパディング部分の値を確認し、署名のときと同じようにメッセージのハッシュ値とソルト値を使ってハッシュ値を求めます。これが、署名によるハッシュ値と一致すれば署名の正当性が検証できたことになります。

このように、PSSではパディングの検証が署名の検証と一体化して行われていることがわかります。

一方、PKCS#1 v1.5のほうは署名用のパディングとしても同じように使用されますが、メッセージのハッシュ値のビット長は暗号化のためのメッセージよりはかなり短いので、ハッシュアルゴリズムごとに決められた固定値DigestInfoがパディングとして埋め込まれます。

### まとめ

最後に、PKCS#1(RFC8017)で使用されているパディングスキームのオプションをまとめます。

|パディング種別|ハッシュ|OID|備考|
|---|---|---|---|
|EMSA-PKCS1-v1_5|MD2|id-md2|limited for compatibility|
||MD5     |id-md5       |limited for compatibility|
||SHA-1   |id-sha1      |limited for compatibility|
||SHA-256 |id-sha224    ||
||SHA-256 |id-sha256    ||
||SHA-384 |id-sha384    ||
||SHA-512 |id-sha512    ||
||SHA-512/224|id-sha512-224||
||SHA-512/256|id-sha512-256||
|OAEP, PSS|SHA-1   |id-sha1       ||
||SHA-256 |id-sha224     ||
||SHA-256 |id-sha256     ||
||SHA-384 |id-sha384     ||
||SHA-512 |id-sha512     ||
||SHA-512/224|id-sha512-224||
||SHA-512/256|id-sha512-256||


表 パディングのハッシュオプション一覧

この記事の内容を含めてTLプログラミングについて解説をまとめる機会をいただきました。興味のあるかたはご覧ください。[徹底解剖 TLS 1.3](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E8%A7%A3%E5%89%96-TLS-1-3-%E5%8F%A4%E5%9F%8E-%E9%9A%86/dp/4798171417/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1WX07IBUINBBR&keywords=%E7%BF%94%E6%B3%B3%E7%A4%BE+TLS&qid=1643343354&sprefix=%E7%BF%94%E6%B3%B3%E7%A4%BE+tls%2Caps%2C177&sr=8-1) (翔泳社から 3/7刊行)。