4つのセキュリティ技術(ハッシュ関数、乱数、共通鍵暗号、公開鍵暗号)について説明します。
これらを実装したコードは組み合わさって様々なところ(オープンソース・プロトコル等)で多用されている。コマンドでも比較的簡単に操作できるようになっている。
ハッシュ関数は、ファイルやデータの完全性(本物か?壊れてないか?)を検証するためによく用いられている。
ハッシュ関数はいくつも種類があり(数学者の競争)、弱い順に例をあげるとMD5、SHA-1、SHA-256など。
MD5はハッシュ値が32文字(数字とa~fの計16種類×32桁)であり、入力値が異なるのにハッシュ値が同一になる確率は、「コインを128回投げたら全部表が出る」のと同じ。
OSS(オープンソースソフト)の公式サイトなどでは、プログラム本体のダウンロードページにハッシュ値の案内があることが多い。そのハッシュ値と、ダウンロードしたファイルに対して自身で出したハッシュ値(下記コマンド)とを比べて、一致していれば「本物、壊れていない、悪の組織がウィルスをこっそり組み込んだりしてない」と判断する。
# MD5の場合
md5sum ダウンロードファイル
乱数は、暗号作成やゲームなどランダムな結果を出すために利用されている。
コンピュータで扱う文字列などすべてのデータは、内部では0と1で表現(符号化/エンコード)されている。この0と1の意味のある並びは、次の手順で意味のない(ランダムな)0と1の並び(完全完璧な暗号)になる。
ポイントは、鍵がランダムならば、排他的論理和によって暗号文も必ずランダムになること。鍵を知らない者は、原理的に、無限の時間をかけても、絶対に100%絶対に平文がわからない。
ゲームに限らないが、プログラミングではランダムを利用することは多い。例として、shuf
コマンドは指定した配列をランダムに返す。
# 「あいうえお」からランダムに出力
shuf -e あ い う え お
あ
お
う
い
え
共通鍵暗号は、暗号化に使う鍵と復号に使う鍵が同じ方式の暗号のこと。その具体的な暗号化手順(アルゴリズム)はいくつもある。
共通鍵は(表面的には)パスフレーズのことなので、強いパスフレーズにして第三者に漏れないようにする。
例として、openssl
コマンドで共通鍵暗号を使ってみる。ここではcamellia256
というアルゴリズムを使っている。
# -eは暗号化
openssl enc -e -camellia256 -in 平文ファイル -out 暗号文ファイル
# -dは復号
openssl enc -d -camellia256 -in 暗号文ファイル -out 復号ファイル
公開鍵暗号は、暗号化の鍵と復号の鍵が別になっていて、作成者だけの秘密にするプライベート鍵をもとに、世界に公開する公開鍵を作る方式の暗号のこと。逆に公開鍵からはプライベート鍵を作ることはできない(宇宙年齢費やすほど困難)。両者の組み合わせを鍵ペアという。
アルゴリズムはRSAや楕円曲線暗号などがある。
プライベート鍵は、(表面的には)プライベート鍵ファイルのことなので、それを強いパスフレーズで守りつつ(暗号化)、第三者に漏れないようにする。
公開鍵は、コマンド一つで世界中にある鍵サーバに公開でき、他人のも入手もできる。
20世紀後半まで暗号といえば共通鍵暗号だったが、鍵を通信相手に渡す過程で第三者に傍受されるリスクがあった(鍵配送問題)。公開鍵暗号では第三者に見られてもいい公開鍵で暗号化し、それは公開鍵では復号できないから鍵配送問題が生じず、暗号文はプライベート鍵の作者のみが復号できる。
「プライベート鍵→公開鍵」という一方向の流れでのみ作成できる仕組みは、数学の一方向性関数を利用している。例として、「素数P × 素数Q = N」における、「NからPとQを逆算するのは困難」という性質。Nは公開鍵、PとQはプライベート鍵に当たる。
公開鍵で暗号化したらペアとなっているプライベート鍵でしか複号できない。
gpg --gen-key
gpg --send-keys 鍵ID
gpg --recv-keys 鍵ID
gpg --list-keys
gpg --recipient 暗号文の受取人 --armor --encrypt 平文ファイル
できた暗号文を送って、
gpg 暗号文ファイル
プライベート鍵で暗号化したら、ペアとなっている公開鍵でしか復号できない。言い方を変えれば、公開鍵で復号できたファイルは、プライベート鍵の保有者が作った本物とわかる。これが「私が作った本物」と証明する電子署名の仕組み。
gpg --gen-key
gpg --send-keys 鍵ID
gpg --local-user 電子署名する人 --detach-sign --armor 署名するファイル本体
本体のファイルとできた分離署名ファイルを送って、
gpg --recv-keys 鍵ID
gpg --list-keys
gpg --verify 分離署名ファイル 本体ファイル