LoginSignup

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

RSA暗号は1文字1文字暗号化しているのでしょうか(なわけないと思うのですが)

Q&AClosed

ネット上でよく見かけるRSA暗号の説明で,平文をコード化するとき,例えば HELLOであれば,

['H', 'E', 'L', 'L', 'O']

をそれぞれ文字コード

[48, 45, 4c, 4c, 4f]

に変換し,1文字1文字を $e$ 乗して

[4242, 42423435, 645646, 645646, 636346]

といった暗号化をする(数字はテキトーです),という書き方をしている記事が異様に多いのですが(例えば公立はこだて未来大学など),これは正しいのでしょうか.1文字1文字暗号化していたら文字数がばれるし,同じ文字があった場合何番目にその文字があるか分かってしまうし,暗号文の並びで母音の e などがどれかすぐに予想できそうな気もするのですが.

実際は,HELLO であれば 16進法で10桁の数

48454c4c4f

を $e$ 乗するのが本来であり,また,長すぎる文字列は適度に分割して暗号化していると思われるのですがいかがでしょうか.暗号理論の専門書に目を通しても一般論しか書かれておらず実装的な部分が詳しく書かれていないことが多いので,もやもやしています.

また,暗号化するのに指数 $e= 65537$ が使われることが多いのは,

  1. そこそこ大きな数だから
  2. 繰り返し 2乗法で高速で計算できるから
  3. 素数ゆえに $\operatorname{lcm}(p-1, q-1)$ と互いに素になりやすいから

などが理由でしょうか.

ご教示お願いします.

1

2Answer

「2つの素数による積」の特性を使っていれば、RSA暗号といえると思います。
ですが「RSA暗号だから1文字1文字処理する」ということはありません。

まず、暗号化の入力データは基本的に、単なるバイナリとして扱われ、入力単位のサイズも実装によりまちまちです。

また、投稿にあるサンプルでは、同じ入力(文字)が同じ出力になっていますが、実用的な暗号化では、前回の出力を入力として扱ったりして、同じソースに対して、違う結果がでる等の工夫がされているはずです。

暗号というのは攻撃者に解読されないように、色々な要素(アイデア)が盛り込まれるため、一概にこうだとは言いにくい部分があります。

暗号理論の専門書に目を通しても一般論しか書かれておらず
実装的な部分が詳しく書かれていないことが多いので,もやもやしています.

この気持ちはよくわかります。
理論よりもコードを読んだほうがピンとくるという方であれば、下記の「Javaで作って学ぶ暗号技術」が超おすすめです。

200ページほどの手ごろな本です。
「アルゴリズムの説明+実際のコード」の構成で、暗号化の基本がテンポよく学習できます。Javaに馴染みがなくても、C系の言語がわかれば無理なく内容を理解できると思います。

3

Comments

  1. @HigashinoSola

    Questioner
    コメントありがとうございます.

    > また、投稿にあるサンプルでは、同じ入力(文字)が同じ出力になっていますが、実用的な暗号化では、前回の出力を入力として扱ったりして、同じソースに対して、違う結果がでる等の工夫がされているはずです。

    数学の理論だけは単純ですけど,どう実装するか色々工夫があるんですね.改めて素人が立ち入ってはいけない世界だなあと思いました.

    > 理論よりもコードを読んだほうがピンとくるという方であれば、下記の「Javaで作って学ぶ暗号技術」が超おすすめです。

    参考書籍の紹介ありがとうございます.早速購入してみます(森北出版は痒いところに手が届くマニアックな本を多く出しているイメージがあります).

一文字ずつ別の文字に置き換える暗号は「換字暗号」と呼ばれるもので、暗号の基本みたいなものなので避けて通るわけにはいかないと思います。
出現頻度によって文字の対応を推測できることも古くから知られていて、シャーロックホームズの「踊る人形」はまさにそういう話です。
その対策としては第二次世界大戦でドイツ軍が使っていたエニグマ暗号では「キーで一文字打つごとに暗号表(置き換えパターン)を切り替える」といったことをしていました。

今では共通鍵暗号の世界では文字列(文字コード列)を一つの大きな桁の数字として暗号化する「ブロック暗号」や、バイト列の並びを順次暗号化していく「ストリーム暗号」が主流です。
これは「鍵さえ知られなければ」非常に強力です。

一方、RSAのような公開鍵暗号は処理が複雑なため大きなデータを暗号化すると非常に時間がかかるので、「鍵さえバレなければ安全」な公開鍵暗号の鍵を安全に受け渡すことなどに使われます。
鍵データであれば中身はただのバイナリデータでしかなく、長さもごく短いため出現頻度から置換パターンを絞り込むことは困難です。

さらにRSA暗号の実装では元データの中にときどき乱数を挿入することで、元のデータとの対応関係を予想することを困難にしているそうです。
(復号側はどこに乱数が入っているかを知っていてその部分を読み飛ばす)

2

Comments

  1. @HigashinoSola

    Questioner
    コメントありがとうございます.

    大きなデータは共通鍵暗号で暗号化し,それを復号するための鍵を公開鍵暗号で暗号化するみたいな使われ方が一般的ということでしょうか(そういえば昔聞いたことがあるような気がします).

    > さらにRSA暗号の実装では元データの中にときどき乱数を挿入することで、元のデータとの対応関係を予想することを困難にしているそうです。

    細かな工夫があるんですね.あまり素人が立ち入ってはいけない世界のように思えてきました.

Your answer might help someone💌