同じ鍵で閉めて、同じ鍵で開ける
共通鍵暗号とは、送る人と受け取る人が同じ鍵を持ち、その鍵でデータを暗号にして、また元に戻す方式です。鍵を知らない人は、通信を盗み見ても中身を読めません。
ノートパソコンの保存データや、社内のファイル転送でいまも広く使われています。このレッスンでは、昔の暗号がなぜ破られたかを通して、鍵の長さの意味を学びます。
このレッスンのゴール
メモ
1つの共通の鍵でデータを暗号にし、元に戻すしくみを説明することができる。
キーワード
| ことば | いみ |
|---|---|
| 平文 | 暗号にする前の、読める文章やデータ |
| 暗号文 | 暗号にしたあとの、読めないデータ |
| 鍵 | 暗号にしたり戻したりするときに使う秘密の値 |
| 暗号化 | 鍵を使って、平文を暗号文にすること |
| 復号 | 鍵を使って、暗号文を平文に戻すこと |
| 総当たり | 鍵を片っ端から試して、当たりを探す攻撃 |
学生が入力するセルは、このプレビューでは空白です。
ずらすだけの暗号はどう働くか
いちばん古い暗号の1つがシフト暗号です。アルファベットを、鍵の数だけ後ろへずらします。鍵が3なら、a は d、b は e になります。
戻すときは、同じ数だけ前へずらします。送る人と受け取る人が、「3」という数を知っていれば成り立ちます。
例: 鍵3で hello を暗号にする
| 内容 | 1文字目 | 2文字目 | 3文字目 | 4文字目 | 5文字目 |
|---|---|---|---|---|---|
| 平文 | h | e | l | l | o |
| 3つ後ろの文字 | k | h | o | o | r |
学生が入力するセルは、このプレビューでは空白です。
hello を鍵3で暗号にする
printf 'hello' | tr 'a-z' 'd-za-c'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
同じ鍵で元に戻す
printf 'khoor' | tr 'd-za-c' 'a-z'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
シフト暗号は数秒で破られる
シフト暗号の鍵は、0から25までの26通りしかありません。全部試しても、人の手で数分です。プログラムなら一瞬です。
この「全部試す」攻撃が総当たりです。暗号の強さは、鍵が何通りあるかで決まります。鍵が長いほど、総当たりに時間がかかります。
例: 鍵の数と総当たりの手間
| 暗号 | 鍵の長さ | 鍵の数 | 総当たりの目安 |
|---|---|---|---|
| シフト暗号 | アルファベット26字 | 26通り | プログラムで一瞬 |
| 昔の短い鍵の暗号 | 56ビット | 約7.2 × 10の16乗 | 現在の機械で現実的に破れる |
| いま使われる暗号 | 128ビット | 約3.4 × 10の38乗 | 現実には試し切れない |
学生が入力するセルは、このプレビューでは空白です。
128ビットの鍵の数を計算する
python3 -c "print(2 ** 128)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
「base64 に変えたから、データは暗号になった」と考える人が多くいます。base64 は文字の書き方を変えるだけで、鍵がありません。誰でも元に戻せるので、秘密を守る目的には使えません。
base64 は鍵なしで戻せる
printf 'abc' | base64ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
鍵なしで元に戻す
printf 'YWJj' | base64 -dここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
現代の共通鍵暗号はブロック暗号
いま使われる共通鍵暗号の多くはブロック暗号です。データを16バイトのような決まった大きさのブロックに分け、鍵を使って何度も混ぜます。AES はその代表です。
混ぜる操作は公開されています。秘密なのは鍵だけです。しくみが知られていても、鍵が秘密なら安全であるべきだからです。
同じ鍵で2回混ぜると元に戻る
python3 -c "print(65 ^ 42, 107 ^ 42)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
混ぜる操作は、同じ鍵で戻せる
先ほどの ^ は、2つの数のビットを混ぜる操作(XOR)です。65を42で混ぜると107になり、107をもう一度42で混ぜると65に戻ります。
これは暗号の考え方を見せる小さな例です。本物の暗号は、もっと複雑に混ぜます。自分で暗号を作らず、検証された既製のライブラリを使いましょう。
Python でシフト暗号を動かす
# 小文字の英字を、鍵の数だけ後ろへずらします。
def shift_letters(text, key):
result = ""
for ch in text:
if "a" <= ch <= "z":
number = (ord(ch) - ord("a") + key) % 26
result = result + chr(number + ord("a"))
else:
result = result + ch
return result
print(shift_letters("sakura", 4))
# 鍵を4から10に変えて、もう一度実行しましょう。
共通鍵暗号の悩みは、鍵の渡し方
共通鍵暗号には弱点があります。相手に鍵を安全に渡す方法が必要です。鍵を普通のメールで送れば、盗まれるかもしれません。
この「鍵の配送問題」を解くために考えられたのが、次のレッスンで学ぶ公開鍵暗号です。