講義用スタイル
印刷用スタイル

RSA 入門


公開鍵暗号は 2つの鍵が1つのペア となっていて、いずれかの鍵 で暗号化した文は もう一方でないと(つまり暗号化した鍵では)元 に 戻らないわけです。しかし、実際にこれがプログラム=計算手続きと してどのように実現できているか、というのは直観的になかなか理解し辛いと 思います。そこで、公開鍵暗号の代表例である RSA について説明し、理解を深 めてもらいます。

これは前述のように、素因数分解の困難性 を利用して一方向の 関数 を得ています。直観的に言うと、7x13 → 91 と計算するのは簡単だ けど、91 がどの2つの素数が掛け合わさっているかを調べるのは簡単ではない (最悪、しらみつぶしに試すしか方法がない?)ということです。

…という説明はかなりおおざっぱです。実際のところ、この方法をきちんと理 解するにはある程度の数学的知識がないと無理なのですが、ここではそこをな んとかして(?)できるだけ簡単に(でもまだ結構複雑かも)説明します。

ちなみに RSA 暗号は Rivest, Shamir, Adleman という3人の研究 者によって考案されたもので RSA とはそれぞれの名前の頭文字を取って付け られたものです。彼らは会社 (RSA Security 社)をつくり、RSA暗号のアルゴ リズムは1983年9月20日にアメリカ合衆国で特許(4,405,829号)が成立しライ センスを独占していましたが、特許期間満了に伴って2000年9月6日からは誰で も自由に使用できるようになりました。

この暗号方式には以下のような特徴があります。

素数と素因数分解

RSA の説明の前に、まず基礎となる概念として、素数と素因数分解について説 明します。素数とは、2以上の整数で 1と自分以外では割れない数 が定義です。なので、2,3,5,7,11…は素数ですが、9 や 15 は素数では ないです(3で割れる)。
定義から明らかに1は素数ではないです。なぜそうなってるかというと、1を 素数にするとあらゆる整数が割り切れてしまうということになり、意味がなく なるからです。
次に、素因数分解についてです。素因数分解とは
24=2*2*2*3
のように、ある数を素数のかけ算 の形にすることです。そして (ここでは証明は略しますが)素因数分解は順番をのぞいて1通り です。多くの場合は昇順=小さい数から先に書く(だんだん大きい数になっ ていく=昇っていく)ことが多いです。この素因数分解が RSA の基盤になって います。2*2*2*3 を計算するのは簡単ですが、24 が何の積になっているかは一 般には割り算を手当たりしだいしないと分らない、ということで、数が大きく なると大変な処理になるというわけです。

素数の求め方

ちなみに、ある数が素数かどうか調べるための古くから知られている代表的な 方法に エラトステネスのふ るいがあります。これは、合成数(素数じゃない数)を「ふるい」落とし てふるい落とされずに残ったものが素数というものです。

たとえば100までの素数を知りたいとすると2から√100 (=10) まで の素数の倍数を消していくのです。

  1. 2は(素数ですから)そのままにして、 2の倍数の4,6,8,10,12,...を候補から消します。
  2. 同様に; と次々に消す=ふるい落としていきます。
  3. 最終的にふるい落とされずにのこった数が素数です。 つまり、 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です。
残った数が素数であることは明らかです(?)…例として97について考えます。
  1. もし97 が素数でないと仮定すると、
    97=α*β*...
    
    のように素因数分解され、このとき、α、β…のどれかは√100=10までの素数 になるはずです。なぜなら全てが10より大きい素数だったら97は 10*10(*...10) である100より大きくなるからです。
  2. α、β…のどれかは√ 100=10 までの素数になるのでそれをαとすると、 97=α*β*... ということは97がαの倍数(β*...倍)なので、αの倍数の ときにふるい落とされているはずなので矛盾します。
  3. よって仮定は偽、つまり97が合成数ではなく素数ということになります。(背理法)
☆ふるい落とされたすべての数について、同じことが言えます。
ちなみに JavaScript で書いた1000までの素数を求 めるスクリプト例 です。

練習問題

次の数を素因数分解しなさい。数字は昇順(小さい数字が左にくる)で、「×」 は "*" (asterisk) で表してください。

15 =
125 =
128 =
1001 =

剰余

次は RSA で重要な概念としての 剰余(整数同士を割り算したときの余り) の取扱いについてです。

これは、言ってみれば0, 1, 2, 3 ……というふうに、普通の整数は、どこまで も延々と続くのですが、あるところまで行くと 0 に戻る、という(循環した) 世界を考える、ということです。例えば、5 まで行くと次は 0 に戻ると考えま す。5+1は、ふつうの計算では6ですが、この世界では6は0に等しいとします。 つまり、この世界では0,1,2,3,4,5 の6通りしかないことになり、これは6 で 割った余りの世界 と考えることができるわけです。この 「余りの世界」 のことを、「剰余系」 と呼びます。

以下では、通常の計算とこの特殊な世界の計算の両方を使うので、混乱しない ように特殊な世界の等しいは ≡ (合同記号)で表します。すると

0+1=1, 1+1=2, 2+1=3, 3+1=4, 4+1=5, 5+1=6≡0, 6+1=7≡1, 7+1=8≡2, ...37≡1
などとなります。すなわち「6を6で割ると余りは0」「37を6で割ると余りは1」 と解釈できます。

何で割ったときの余りかを明示するために、

37≡1 (mod 6)
と書いて「6を法 (modulo) にすると37と1は等しい(または37と1は 合同 )」と言います。このように≡の「等しい」は何を法にするか によって成り立ったり成り立たなかったりするので注意が必要です。とはいえ 前後の流れから分かるときは、法を明示しない場合もあります。

剰余系の性質

「modを求める」演算(これが則ち剰余演算)と、足し算やかけ算は、どちら を先にやっても同じです。
19 + 36 = 55 ≡ 5 (mod 10)
これは55を10で割ると余りは5だ、ということです。そして
19≡9 (mod 10)
36≡6 (mod 10)
19 + 36 ≡ 9 + 6 = 15 ≡ 5 (mod 10)
というふうに、先に余りを求めて、余りどうしを足しても、結果は同じです。 実際、商 q1, q2 と余り r1, r2 を使って
a = 10q1 + r1
b = 10q2 + r2
となっているとき、和
a + b = 10(q1+q2) + (r1+r2)
の右辺第一項は10で割り切れるので、a+b を10で割ったときの余りは (r1+r2) にのみ依存します。これは先に余りを求めて 余り同士を足しても同じ、ということを意味しています。法が10の場合は、要 するに10進数の下1桁だけ計算すればいい、ということで直観的に理解でき ると思いますが、法は10でなくても同じことです。特に乗算の場合には、先に 余りを求められることが役立ちます。
12345678912≡2 (mod 10)
9876543≡3 (mod 10)
なので、この場合、12345678912 x 9876543を実際に計算しなくても、この積の 剰余を求めるだけなら 2x3→6 (mod 10) になります。また、
98765434≡34=81≡1 (mod 10) 
などとできます。9876543の4乗を10で割った余りを計算する時には、素直にこ の数の4乗など計算しなくても、先に10で割って、その余りを4乗するだけで良 いです。

練習問題

次の数の剰余を求めなさい(要するに、23 で割った余りは何ですか?という ことです)。

10 ≡ 」(mod 23)
100 ≡ 」(mod 23)
1000 ≡ 」(mod 23)
73 」(mod 23)


フェルマーの小定理

フェルマーの小定理は、「素数 p に対して、任意の整数 n の p 乗 を p で割ると余りは n に戻る」というものです。例えば、素数 7 に対して
27 = 128 → 7で割ると商18、余り2
37 = 2187 → 7で割ると商312、余り3
47 = 16384 → 7で割ると商2340、余り4
57 = 78125 → 7で割ると商11160、余り5
……
というふうになり、余りは7乗されたもとの数に戻ります。式で書けば、
np ≡ n (mod p)
となります。例えば、
107 = 10000000
の場合、7で割ると商1428571、余り3ですが、3は7を法として10と合同ですから、やっぱり
107 ≡ 10 (mod 7)
が成り立ってます。「7で割った余りで考える世界」では、3も10も73も同じグ ループとして同一視するということです。

フェルマーの小定理は「pを法とする世界で考えると、どんな数もp乗すれ ば自分自身に戻る」ととらえることができます。つまり、上で見た通り、 例えば7を法とした世界では、3 の7乗は3自身と合同、4の7乗は4自身と合同、 5の7乗は5自身と合同…となります。再掲しますので再確認してください。

27 = 128 → 7で割ると商18、余り2
37 = 2187 → 7で割ると商312、余り3
47 = 16384 → 7で割ると商2340、余り4
57 = 78125 → 7で割ると商11160、余り5
……
上の各行の左端には2とか3とか4とか5があって、右端には、ふたたびその左端 の数が現れてます。このことを公開鍵暗号系のイメージと重ねると、暗号化と 復号化の合成写像がちょうど上の計算になるようにうまく定義すると、受信者 は暗号化された文章をもとの文章に復元できる、ということがなんとなくイメー ジ出来ると思います。この計算は「もとに戻ることが保証されている」 ところが重要です。すなわち、いくら解読が難しい暗号文を作っても元に 戻せなければ意味が無いというわけです。

素数ではない場合には、この式はなりたちません。例えば、

38 = 6561 → 8で割ると商820余り1
となって、余りは3に戻りません。つまり素数じゃない8ではうまくいかないで す。しかし、
35 = 243 → 5で割ると余り3
37 = 2187 → 7で割ると余り3
のように、指数が5や7といった素数のときは、ちゃんと余りがもとの数と合同 になります。

フェルマーの小定理の 系(というのは数学用語ですが、或 る定理から比較的簡単に導かれる別の定理のようなもの、という感じでとらえ ておいてください) として「素数 p に対して、勝手な整数 n の p-1 乗を p で割ると余りは 1 に戻る」があります。すなわち
ap-1≡ 1(mod p)
となります。これは、元の定理の両辺をaでわれば簡単に導かれます。さらに 系として
「p が素数で x ≡ 1(mod (p-1)) を満たすとき任意の a に対して
ax≡ a(mod p)
」となります。この系がRSAでは重要な役割りをはたします。
というのは、非常におおまかに説明すると x-1 は p-1 で割り切れるので、あ る整数 q によって x-1=q(p-1) と書け、a'=a (mod p) とすると
ax
≡ (a')x
≡(a')q(p-1)+1
≡ (a')q(p-1)*(a') ≡ ((a')p-1)q*(a') 
≡ 1q*(a') ≡ a' ≡a(mod p)
であるからです。

いよいよ RSA

準備が整ったところで、RSA暗号の基本的な原理や使用法を説明します。まず 暗号化を行う前に予め以下の手順に従って秘密鍵と公開鍵を作成しておく必要 があります。
  1. 2つの大きな素数 p,q を選択します。
  2. n = p*q とφ(n)=(p-1)(q-1)を計算します。 このnは係数と呼ばれます。
  3. gcd(e,φ(n))=1の関係をもつ、すなわちφと互いに素になる乱数 e(公開 指数)を選択します。
    gcdとは与えられた2つの数の最大公約数です。つまり、それが 1ということは、互いに素(=素因数分解した時に、共通する素因数が無い) ということです。
    この公開指数 e と係数 n が公開鍵 (e,n) となります。
  4. e*d (mod φ(n)) ≡ 1 となる d(秘密指数)を計算します。 この秘密指数 d と係数 n が秘密鍵 (d,n) となります。

暗号化と復号化

平文をM, 暗号文を C とすると, M < n であれば、以下の関係式が必ず成り立ちます。
C≡Me (mod n)
M≡Cd  (mod n)
これらの関係式が必ず成り立つという(数学的)特性が RSA 暗号の原理 です。これは上のフェルマーの小定理を使うことにより証明できますが、 詳細は略します。
…だけではなんなので、大まかな説明は以下の通りです。
ここでいくら暗号文 C, 係数 n および公開指数 e の値を知っていたとし ても、秘密指数 d の値を知らなければ暗号文 C から平文 M を得ることは (計算量的に)ほぼ不可能 です。これがRSA暗号の安全性の保証と なってるわけです。
ちなみに、一度に暗号化できるデータは n 以下の数値 であることも 留意してください。例えば n が 1024bit の数値であれば、長い平文であった 場合はその 文字コード=数値 を(安全を見越して) 1023bit 以下 毎に分けてから暗号化しないといけないことになります。

RSA暗号の実行例

ここでは、鍵の作成から暗号化、復号化までの一連の流れの例を示します。
ただし分かりやすくするために非常に小さい=安全でない鍵を使っている、と いうことは把握しておいてください。現実社会では最近では計算機能力の向上 にあわせて2048 (or 4096)bit長の数値を使っています。

鍵の作成

AさんはBさんからネットワークを介してある極秘情報が記載された重要文書 M (その内容は簡単のため数値化されているとし、仮に3であるとします)を受 け取りたいのでAさんはBさんにRSA暗号を用いて暗号化して送ってもらおうと します。
文書を数値化するというのは特別な仮定ではなく、一般的なことです。たとえ ば "ABC" という文字列は ASCII では16進数で '414243' となりますが、これ は 65*256*256+66*256+67=4276803という整数として扱うことが出来るわけです。
そのためにAさんは秘密鍵 (d,n) を、Bさんはそれに対応する公開鍵 (e,n) をそれぞれ持っていなければなりません。まず A さんはそれらを作成 します。
  1. まず2つの素数として、例えば p=7, q=11 を選びます。

  2. 次に、これらを用いて n とφ(n)を求めると
    n = 7*11 = 77
    φ(n) = 6 * 10 = 60
    
    となります。

  3. 続いて、gcd(e,φ(n)) = 1の関係をもつ乱数 e(公開指数)を選択します。 ここでは e を13とします。φ(n) を素因数分解すると 2x2x3x5 なので 確かに互いに素になっています。
    この e も、下の d にしても、元の素数から一意に決まるわ けではなく、条件を満たせば任意のものが選べます。
  4. 次に秘密指数 d を計算します。つまり 1 ≡ e*d (mod φ(n)) になるよ うな d を求めます。このあたりは実際にはツール(パスフレーズと乱数を用 いる)でやるのですが、結論から言うとここでは d=37 とできます。たしかに
    d*e=37*13=481≡1(mod 60)  
    
    となっています。

  5. これで公開鍵 (e,n) が求まったので、Aさんは公開鍵 (13,77) だけをBさ んに知らせます。確証さえあたえられれば電子メールで送っても構いません。 ただし知らせてもよいのは公開鍵だけでありd,p,q の値は絶対に知られてはい けません。

暗号文の作成と復号

Aさんから公開鍵を受け取ったBさんは、早速上述した暗号化の式を使って 重要文書 M (内容は3)を暗号化します。
Me = 313 = 1594323 ≡ 38 (mod 77) ⇒ C=38
Bさんはこの暗号文C=38をメールでAさんに送ります。

Bさんから送られた暗号文を受け取ったAさんは、早速上述した復号化の式を使って

Cd = 3837 
= 28313468473157736370011296127792731029354930758695159595008
≡ 3 (mod 77) ⇒ M=3
以上のような暗号処理によりAさんはBさん以外の誰にも重要文書の元の内容を 知られることなく無事にその内容M(=3)を得られます。

ちなみに署名についても上とほぼ同様で、MD5 かなにかでダイジェスト(ハッ シュ)をつくって、それを自分の秘密鍵で暗号化すれば、それを元に戻せるの は自分の公開鍵だけですから認証できるわけです。

RSA暗号の安全性

RSA暗号の安全性の前提は大きな数を素因数分解するのが難しいとい うことから上述した暗号化の式が一方向性である、つまり攻撃者が 暗号文を復号化することが計算量的に困難であるという仮定にもとづ いてます。RSA暗号はこれまで多くの人々の間で使われてきましたが、実際にこ れまでその破り方を見つけられていないということによって信頼性を得ていま す。

もし素因数分解を簡単に行うことができれば、RSAを破ることは可能です。公 開鍵 (e, n) を知っていて、もし n を素因数分解して p,q を知ることができ れば秘密指数dはそれらから簡単に計算できます。とはいえ、例えば n が 2048bit だと10進数で六百桁くらいの数値なので、素因数分解するのに何十年 もかかる=現実的には解けない、という期待なわけです。

とはいえ量子コンピュータが実現すれば比較的簡単にとけるとされていますし、 そもそも n を素因数分解することだけがRSAを破る唯一の方法かどうかは分かっ ていない(証明されていない)のが現状です。

RSA暗号の正しい使い方(補足)

ちなみに RSAの使い方を誤ると秘密鍵を知らない者によって n を素因数分解す ることなしに暗号文と公開鍵から平文を求められてしまう場合があります。例 えば5人の中から一人を選んでその名前の文字列を暗号化して送ること(電子 投票?)を考えてみましょう。その場合、送られた暗号データを盗聴した者 (公開鍵 (e,n) のみを知っている)はその暗号データが誰の名前を暗号化し たものかが簡単に分かります。というのは5人の各候補者の名前をそれぞれ 既知の公開鍵で暗号化してみてその中から盗聴した暗号データと一 致するものを調べれば元の投票データがどの候補者の名前であるかが分かるか らです。この場合盗聴した者は多くとも5通り試すだけで内容(平文)を知る ことができるのです。

何故このような問題が起こるのかと言えば、RSA暗号の使い方が誤っているか らなのです。つまり平文の「場合の数」(種類)が少ければ、その 数だけを試すことで解けるからです。

なので、この場合は内容である名前の前(か後ろ)に大きな乱数を連結 (「1357前田」のような形式)した上で暗号化すれば解決できます。

このような追加するデータのことをソルト と呼ぶことがあります。
例えば乱数の大きさと して 128 ビットを取れば、投票された暗号データを盗聴した者は5通りではな く5x2128 通り の暗号化及び比較をしなくてはならなく なりますが、それは計算量的に不可能、というわけです。

講義用スタイル
印刷用スタイル (開いてから、ページを再度更新してください)