RSA鍵生成脆弱性ROCAの紹介
2017/11/13
光成滋生
• 論文
• The Return of Coppersmith's Attack Practical Factorization of
Widely Used RSA Moduli
• https://acmccs.github.io/papers/p1631-nemecA.pdf
• 主な内容
• 主要な暗号ハードウェアメーカで使われているライブラリ
(RSALib)の鍵生成アルゴリズムの欠陥を見つけた
• そのRSALibで作られた1024~2048bit RSAの公開鍵のみで
復号可能なアルゴリズムの提案
• OpenSSLで作ったものは大丈夫
• RSALibで作られた鍵かどうかを公開鍵のみで高速に判定可能
• TPMやeIDなどで利用されていることを調査
概要
2 / 17
• 今回の手法を適用したときの解読コスト
• p.10 Table 2
• 2048bit RSAの解読が現実的
Nの素因数分解にかかるコスト評価
3 / 17
• 異なる41個のPCのうち6個のTPM製品に脆弱性
• https://www.kb.cert.org/vuls/id/307015
• エストニアeIDのランダムサンプリングの54%に脆弱性
影響を受けるもの
4 / 17
• 異なる2個の素数𝑝と𝑞を選ぶ
• 𝑁 = 𝑝𝑞, 𝜙 𝑁 = (𝑝 − 1)(𝑞 − 1)とする
• 𝜙(𝑁)と互いに素な𝑒 < 𝜙(𝑁)を選ぶ
• 𝑑 = 𝑒−1 mod 𝜙(𝑁)とする
• mod 𝑥は𝑥で割った余り
• (𝑒, 𝑁)が公開鍵
• 𝑑が秘密鍵
RSA暗号
5 / 17
• 素数定理
• 𝑥以下の素数の個数𝜋(𝑥)はおおよそ𝑥/log(𝑥)である
• ガウスが15歳のとき素数を数えてその予想を立てたらしい
• 𝑛 bit素数なら
• 2 𝑛−1 ≤ 𝑝 < 2 𝑛
• この範囲の素数は𝜋 2 𝑛 − 𝜋 2 𝑛−1 =
2 𝑛
0.7𝑛
−
2 𝑛−1
0.7 𝑛−1
~2 𝑛−1/𝑛
• 512-bit RSAなら𝑛 = 256なので2247個程度
• 結構たくさんある
素数の個数
6 / 17
• 𝑝 = 𝑘𝑀 + (65537 𝑎 mod 𝑀)の形をしていた(と推測)
• ここで𝑎, 𝑘が動くパラメータ
• 𝑀はRSA暗号の鍵長のみに依存する定数
• 𝑃𝑛# ≔ 2 ∗ 3 ∗ ⋯ ∗ 𝑃𝑛 ; 素数を小さい順にn個掛けたもの
• 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
139, 149, 151, 157, 163, 167, ...
• 512bit RSAなら𝑀 = 𝑃39#
• 1024bit RSAなら𝑀 = 𝑃71#
• 2028bit RSAなら𝑀 = 𝑃126#
• 512bit RSAなら𝑘の範囲は37bit, 𝑎は62bitらしい
• エントロピー(自由度は)37+62=99bit
• 本来の素数の個数247bitに比べてずっと少ない
RSALibが生成する素数
7 / 17
• 𝑝 = 𝑘𝑀 + 65537 𝑎 mod 𝑀
• 𝑞 = 𝑙𝑀 + (65537 𝑏 mod 𝑀), 𝑎, 𝑏, 𝑘, 𝑙 ∈ ℤなので
• 𝑝 ≡ 65537 𝑎
(mod 𝑀), 𝑞 ≡ 65537 𝑏
(mod 𝑀)
• よって𝑁 = 𝑝𝑞 ≡ 65537 𝑐(mod 𝑀), 𝑐 = 𝑎 + 𝑏の形となる
• この論文の一つ目の貢献
• 𝑁が与えられたときに
𝐷𝐿𝑃 𝑁 ≔
𝑁 = 65537 𝑐 mod 𝑀となる𝑐
存在しない
を高速に求める方法
• 𝐷𝐿𝑃(𝑁)が求まるなら無視できる確率を除いて
𝑁はRSALibで生成されたもの
• 公開鍵をみて脆弱だと分かってから攻撃可能
RSALibが生成する素数の指紋
8 / 17
• 年齢当てクイズ
• あなたの年齢の3で割った余り、5で割った余り、7で割った余
りを教えてください
• 𝑥 % 3, 𝑦 % 5, 𝑧 % 7から0 ≤ 𝑥 < 3 ∗ 5 ∗ 7 = 105の範囲で求まる
• 105は3と5と7の最小公倍数
• 中国剰余定理(CRT : Chinese Remainder Theorem)
• 𝑛1, … , 𝑛 𝑘を互いに素, 𝑥が未知, 𝑎1, … , 𝑎 𝑘が既知のとき
𝑥 ≡ 𝑎1 mod 𝑛1 ,
...
𝑥 ≡ 𝑎 𝑘 mod 𝑛 𝑘 ,
が与えられると𝑥 mod 𝑛1 ⋯ 𝑛 𝑘 を容易に求められる
百五減算
9 / 17
• 𝑦 = 𝑔 𝑥 mod 𝑀のDLPは𝜙(𝑀)の素因数ごとにDLPを解い
てCRTでくっつければよい
• ElGamal暗号などでは大きな素因数を持たせるため解けない
• 詳細は『クラウドを支えるこれからの暗号技術』をみてね
• 𝑀が𝐵 −smooth(DLPの解きやすさを表す指標)
• ⟺ある定数𝐵に対して𝑀の素因数は全て𝐵より小さい
• 𝑀 = 𝑃𝑛#は素数を小さいものから順に掛けていた
• 𝑀, 𝜙(𝑀)は(その大きさに比べて)とてもsmooth
• 効率よくDLPを求められる
• RSALibが生成した公開鍵である⟹ DLP(𝑁)が容易
Pohlig-Hellmanアルゴリズム
10 / 17
• その逆
一般の𝑁でDLP(𝑁)が容易なのはどれぐらいあるのか?
• (答え)とても少ない
• 𝐺 = {65537𝑖 mod 𝑀|𝑖 = 0,1, … }の大きさ
• 𝑜𝑟𝑑 𝑀 65537 =「65537𝑖 ≡ 1 mod 𝑀 となる最小の𝑖 > 0」
• 512bit RSAで62bit
• 262/2216程度の確率(無視できる)
• RSALibが生成した公開鍵である⟺ DLP(𝑁)が容易
• 𝐷𝐿𝑃(𝑁)を計算することで脆弱だと判定可能
擬陽性
11 / 17
• 鍵が脆弱化かどうかを判定するツール
• https://github.com/crocs-muni/roca
• 肝はhas_fingerprint_moduli()
ROCA detection tool
# modulusが公開鍵N
primes = [3, 5, 7, 11, ...
prints = [6, 30, 126, 1026, ...
def has_fingerprint_moduli(modulus):
for i in range(0, len(primes)):
if (1 << (modulus % primes[i])) & prints[i] == 0:
return False
return True
12 / 17
• 各𝑝に対して𝑔 = 65537 % 𝑝としてG = {𝑔𝑖} を求める
• 𝑁 % 𝑝が𝐺に入っていなければ脆弱でない
• prints[i] = calcG(primes[i])
prints[]は何?
def calcG(p):
g = 65537 % p
y = 1
G = set()
for i in range(p):
y = (y * g) % p
G.add(y)
r = 0
for x in G:
r = r | (1 << x)
return r
13 / 17
• Coppersmith法の応用
• 法つき整数係数1変数多項式𝑓 𝑥 ≡ 0(mod 𝑁)の解法
• Howgrave-Graham, Alexander Mayなどによる様々な改良
• 今回は𝑝 = 𝑘𝑀 + (65537 𝑎 mod 𝑀)の𝑎を固定するごとに決まる
𝑘に関する1変数多項式の求解にCoppersmith法を利用
• ただし𝑎の種類は𝑜𝑟𝑑 = 𝑜𝑟𝑑 𝑀(65537)だけあり、とても無理
• これを減らす手法も提案
• p.5 Table 1
この論文のメインの解読アイデア
提案手法による𝑎の種類の削減
14 / 17
• 𝑥と𝑝|𝑁が未知で多項式𝑓 𝑥 ≡ 0 (mod 𝑝)を解きたい
• 𝑥0 < 𝑋という範囲制約パラメータ𝑋を導入
• 𝑓(𝑥)から𝑥 = 𝑥0を解に含む方程式𝑔 𝑥 = 0を沢山構成
• 𝑓から適切な多項式𝑓𝑖を作り𝐿 = {𝑔 𝑥 = 𝑎𝑖 𝑓𝑖(𝑥)𝑖 }を作る
• 𝑔1, 𝑔2 ∈ 𝐿なら𝑔1 ± 𝑔2 ∈ 𝐿という性質がある
• 𝐿は格子点の集合
• 𝐿の中からLLLアルゴリズムを使ってよい𝑔(𝑥)を見つける
• その𝑔は 𝑔 𝑥0 < 𝑝となるので𝑔 𝑥0 = 0
• 𝑔 𝑥 = 0を解いて𝑥 = 𝑥0を求める
• Berlekamp-Zassenhause法など
この論文のCoppersmith法
15 / 17
• 𝑝 = 𝑘𝑀 + (65537 𝑎 mod 𝑀) ---☆なので
𝑓 𝑥 = 𝑥 + 𝑀−1
mod 𝑀 ∗ (65537 𝑎
mod 𝑀)とすると
𝑘は𝑓 𝑥 = 0(mod 𝑝)の解
• 𝑝, 𝑞は𝑁の半分なので𝛽 = 0.5として𝑝 < 𝑁 𝛽
• ☆の性質を満たす𝑀の小さい約数𝑀′を選ぶ
• 解の上限は𝑋 = 2𝑁 𝛽/𝑀′
• for 𝑎′ ←ある固定範囲
• 𝑘′ ← 𝐶𝑜𝑝𝑝𝑒𝑟𝑠𝑚𝑖𝑡ℎ 𝑓 𝑥 , 𝑁, 𝛽, 𝑋
• 𝑝 ← 𝑘′ 𝑀′ + (65537 𝑎′
mod 𝑀′)
• 𝑁 mod 𝑝 = 0なら見つかった/無ければ次の𝑎′
アルゴリズム
16 / 17
• 総計算時間 𝑇𝑖𝑚𝑒 = 𝑜𝑟𝑑 𝑀′ 65537 ∗ 𝑇(𝑀′)
• 𝑇(𝑀′) : Coppersmithを解く時間
• 𝑀′
が大きいほど速い・log2 𝑀′
> log2(𝑁)/4が必要
• ループ回数𝑜𝑟𝑑 𝑀′(65537)
• 𝑀′が小さいほど速い
• 𝑇𝑖𝑚𝑒が小さくなるように𝑀′を選ぶ
• ヒューリスティック
• 他にも改良パラメータ𝑚, 𝑡(略)
• これらのパラメータは
鍵サイズにのみ依存
• よいところを選んで実際に解く
パラメータの選び方
17 / 17

RSA鍵生成脆弱性ROCAの紹介

  • 1.
  • 2.
    • 論文 • TheReturn of Coppersmith's Attack Practical Factorization of Widely Used RSA Moduli • https://acmccs.github.io/papers/p1631-nemecA.pdf • 主な内容 • 主要な暗号ハードウェアメーカで使われているライブラリ (RSALib)の鍵生成アルゴリズムの欠陥を見つけた • そのRSALibで作られた1024~2048bit RSAの公開鍵のみで 復号可能なアルゴリズムの提案 • OpenSSLで作ったものは大丈夫 • RSALibで作られた鍵かどうかを公開鍵のみで高速に判定可能 • TPMやeIDなどで利用されていることを調査 概要 2 / 17
  • 3.
    • 今回の手法を適用したときの解読コスト • p.10Table 2 • 2048bit RSAの解読が現実的 Nの素因数分解にかかるコスト評価 3 / 17
  • 4.
    • 異なる41個のPCのうち6個のTPM製品に脆弱性 • https://www.kb.cert.org/vuls/id/307015 •エストニアeIDのランダムサンプリングの54%に脆弱性 影響を受けるもの 4 / 17
  • 5.
    • 異なる2個の素数𝑝と𝑞を選ぶ • 𝑁= 𝑝𝑞, 𝜙 𝑁 = (𝑝 − 1)(𝑞 − 1)とする • 𝜙(𝑁)と互いに素な𝑒 < 𝜙(𝑁)を選ぶ • 𝑑 = 𝑒−1 mod 𝜙(𝑁)とする • mod 𝑥は𝑥で割った余り • (𝑒, 𝑁)が公開鍵 • 𝑑が秘密鍵 RSA暗号 5 / 17
  • 6.
    • 素数定理 • 𝑥以下の素数の個数𝜋(𝑥)はおおよそ𝑥/log(𝑥)である •ガウスが15歳のとき素数を数えてその予想を立てたらしい • 𝑛 bit素数なら • 2 𝑛−1 ≤ 𝑝 < 2 𝑛 • この範囲の素数は𝜋 2 𝑛 − 𝜋 2 𝑛−1 = 2 𝑛 0.7𝑛 − 2 𝑛−1 0.7 𝑛−1 ~2 𝑛−1/𝑛 • 512-bit RSAなら𝑛 = 256なので2247個程度 • 結構たくさんある 素数の個数 6 / 17
  • 7.
    • 𝑝 =𝑘𝑀 + (65537 𝑎 mod 𝑀)の形をしていた(と推測) • ここで𝑎, 𝑘が動くパラメータ • 𝑀はRSA暗号の鍵長のみに依存する定数 • 𝑃𝑛# ≔ 2 ∗ 3 ∗ ⋯ ∗ 𝑃𝑛 ; 素数を小さい順にn個掛けたもの • 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, ... • 512bit RSAなら𝑀 = 𝑃39# • 1024bit RSAなら𝑀 = 𝑃71# • 2028bit RSAなら𝑀 = 𝑃126# • 512bit RSAなら𝑘の範囲は37bit, 𝑎は62bitらしい • エントロピー(自由度は)37+62=99bit • 本来の素数の個数247bitに比べてずっと少ない RSALibが生成する素数 7 / 17
  • 8.
    • 𝑝 =𝑘𝑀 + 65537 𝑎 mod 𝑀 • 𝑞 = 𝑙𝑀 + (65537 𝑏 mod 𝑀), 𝑎, 𝑏, 𝑘, 𝑙 ∈ ℤなので • 𝑝 ≡ 65537 𝑎 (mod 𝑀), 𝑞 ≡ 65537 𝑏 (mod 𝑀) • よって𝑁 = 𝑝𝑞 ≡ 65537 𝑐(mod 𝑀), 𝑐 = 𝑎 + 𝑏の形となる • この論文の一つ目の貢献 • 𝑁が与えられたときに 𝐷𝐿𝑃 𝑁 ≔ 𝑁 = 65537 𝑐 mod 𝑀となる𝑐 存在しない を高速に求める方法 • 𝐷𝐿𝑃(𝑁)が求まるなら無視できる確率を除いて 𝑁はRSALibで生成されたもの • 公開鍵をみて脆弱だと分かってから攻撃可能 RSALibが生成する素数の指紋 8 / 17
  • 9.
    • 年齢当てクイズ • あなたの年齢の3で割った余り、5で割った余り、7で割った余 りを教えてください •𝑥 % 3, 𝑦 % 5, 𝑧 % 7から0 ≤ 𝑥 < 3 ∗ 5 ∗ 7 = 105の範囲で求まる • 105は3と5と7の最小公倍数 • 中国剰余定理(CRT : Chinese Remainder Theorem) • 𝑛1, … , 𝑛 𝑘を互いに素, 𝑥が未知, 𝑎1, … , 𝑎 𝑘が既知のとき 𝑥 ≡ 𝑎1 mod 𝑛1 , ... 𝑥 ≡ 𝑎 𝑘 mod 𝑛 𝑘 , が与えられると𝑥 mod 𝑛1 ⋯ 𝑛 𝑘 を容易に求められる 百五減算 9 / 17
  • 10.
    • 𝑦 =𝑔 𝑥 mod 𝑀のDLPは𝜙(𝑀)の素因数ごとにDLPを解い てCRTでくっつければよい • ElGamal暗号などでは大きな素因数を持たせるため解けない • 詳細は『クラウドを支えるこれからの暗号技術』をみてね • 𝑀が𝐵 −smooth(DLPの解きやすさを表す指標) • ⟺ある定数𝐵に対して𝑀の素因数は全て𝐵より小さい • 𝑀 = 𝑃𝑛#は素数を小さいものから順に掛けていた • 𝑀, 𝜙(𝑀)は(その大きさに比べて)とてもsmooth • 効率よくDLPを求められる • RSALibが生成した公開鍵である⟹ DLP(𝑁)が容易 Pohlig-Hellmanアルゴリズム 10 / 17
  • 11.
    • その逆 一般の𝑁でDLP(𝑁)が容易なのはどれぐらいあるのか? • (答え)とても少ない •𝐺 = {65537𝑖 mod 𝑀|𝑖 = 0,1, … }の大きさ • 𝑜𝑟𝑑 𝑀 65537 =「65537𝑖 ≡ 1 mod 𝑀 となる最小の𝑖 > 0」 • 512bit RSAで62bit • 262/2216程度の確率(無視できる) • RSALibが生成した公開鍵である⟺ DLP(𝑁)が容易 • 𝐷𝐿𝑃(𝑁)を計算することで脆弱だと判定可能 擬陽性 11 / 17
  • 12.
    • 鍵が脆弱化かどうかを判定するツール • https://github.com/crocs-muni/roca •肝はhas_fingerprint_moduli() ROCA detection tool # modulusが公開鍵N primes = [3, 5, 7, 11, ... prints = [6, 30, 126, 1026, ... def has_fingerprint_moduli(modulus): for i in range(0, len(primes)): if (1 << (modulus % primes[i])) & prints[i] == 0: return False return True 12 / 17
  • 13.
    • 各𝑝に対して𝑔 =65537 % 𝑝としてG = {𝑔𝑖} を求める • 𝑁 % 𝑝が𝐺に入っていなければ脆弱でない • prints[i] = calcG(primes[i]) prints[]は何? def calcG(p): g = 65537 % p y = 1 G = set() for i in range(p): y = (y * g) % p G.add(y) r = 0 for x in G: r = r | (1 << x) return r 13 / 17
  • 14.
    • Coppersmith法の応用 • 法つき整数係数1変数多項式𝑓𝑥 ≡ 0(mod 𝑁)の解法 • Howgrave-Graham, Alexander Mayなどによる様々な改良 • 今回は𝑝 = 𝑘𝑀 + (65537 𝑎 mod 𝑀)の𝑎を固定するごとに決まる 𝑘に関する1変数多項式の求解にCoppersmith法を利用 • ただし𝑎の種類は𝑜𝑟𝑑 = 𝑜𝑟𝑑 𝑀(65537)だけあり、とても無理 • これを減らす手法も提案 • p.5 Table 1 この論文のメインの解読アイデア 提案手法による𝑎の種類の削減 14 / 17
  • 15.
    • 𝑥と𝑝|𝑁が未知で多項式𝑓 𝑥≡ 0 (mod 𝑝)を解きたい • 𝑥0 < 𝑋という範囲制約パラメータ𝑋を導入 • 𝑓(𝑥)から𝑥 = 𝑥0を解に含む方程式𝑔 𝑥 = 0を沢山構成 • 𝑓から適切な多項式𝑓𝑖を作り𝐿 = {𝑔 𝑥 = 𝑎𝑖 𝑓𝑖(𝑥)𝑖 }を作る • 𝑔1, 𝑔2 ∈ 𝐿なら𝑔1 ± 𝑔2 ∈ 𝐿という性質がある • 𝐿は格子点の集合 • 𝐿の中からLLLアルゴリズムを使ってよい𝑔(𝑥)を見つける • その𝑔は 𝑔 𝑥0 < 𝑝となるので𝑔 𝑥0 = 0 • 𝑔 𝑥 = 0を解いて𝑥 = 𝑥0を求める • Berlekamp-Zassenhause法など この論文のCoppersmith法 15 / 17
  • 16.
    • 𝑝 =𝑘𝑀 + (65537 𝑎 mod 𝑀) ---☆なので 𝑓 𝑥 = 𝑥 + 𝑀−1 mod 𝑀 ∗ (65537 𝑎 mod 𝑀)とすると 𝑘は𝑓 𝑥 = 0(mod 𝑝)の解 • 𝑝, 𝑞は𝑁の半分なので𝛽 = 0.5として𝑝 < 𝑁 𝛽 • ☆の性質を満たす𝑀の小さい約数𝑀′を選ぶ • 解の上限は𝑋 = 2𝑁 𝛽/𝑀′ • for 𝑎′ ←ある固定範囲 • 𝑘′ ← 𝐶𝑜𝑝𝑝𝑒𝑟𝑠𝑚𝑖𝑡ℎ 𝑓 𝑥 , 𝑁, 𝛽, 𝑋 • 𝑝 ← 𝑘′ 𝑀′ + (65537 𝑎′ mod 𝑀′) • 𝑁 mod 𝑝 = 0なら見つかった/無ければ次の𝑎′ アルゴリズム 16 / 17
  • 17.
    • 総計算時間 𝑇𝑖𝑚𝑒= 𝑜𝑟𝑑 𝑀′ 65537 ∗ 𝑇(𝑀′) • 𝑇(𝑀′) : Coppersmithを解く時間 • 𝑀′ が大きいほど速い・log2 𝑀′ > log2(𝑁)/4が必要 • ループ回数𝑜𝑟𝑑 𝑀′(65537) • 𝑀′が小さいほど速い • 𝑇𝑖𝑚𝑒が小さくなるように𝑀′を選ぶ • ヒューリスティック • 他にも改良パラメータ𝑚, 𝑡(略) • これらのパラメータは 鍵サイズにのみ依存 • よいところを選んで実際に解く パラメータの選び方 17 / 17