セキュリティには「ハッシュ関数」による処理が欠かせません。もともと処理能力を向上させたり,アクセスに便利なデータ構造を実現するための技術でしたが,認証や電子署名でも使われています。

 ハッシュ関数とは,何らかの数値が入力されて,何らかの数値が出力される仕掛けの一つです。同じ数値を入力する限り,必ず同じ数値が出力されます。偶然性はなく,その時々で出力値が異なることはありません。このような関数がセキュリティで何の役に立つのかを解説する前にまず,ハッシュ関数とはどのようなものなのかをお話ししましょう。

 コンピュータ・プログラムでは,図1のような配列変数というものを使います。この配列変数にはインデックス番号が付いていて,その番号でデータの値を検索します。皆さんが学校時代に慣れ親しんだ出席番号もインデックスです。マンションの部屋番号も一種のインデックスです。このような配列変数は,ほとんどのプログラミング言語にありますが,実際のデータとの関連付けが難しく,初心者にも使いづらいものでした。

図1●通常の配列変数の場合
図1●通常の配列変数の場合
配列変数はインデックス(数値)で値が検索できる。

 そこでperlやJavaのような言語では,ハッシュ・テーブルを使うことができます。ハッシュ・テーブルは,インデックスが必ずしも数値でなくても構いません。例えば,図2のようなハッシュ・テーブルで,「山梨」というインデックスに対し「もも」というデータが検索される表を作れます。これは内部で,「山梨」という文字を何らかの数値に変換して,それをインデックス番号として表を検索しています。

図2●ハッシュ・テーブル
図2●ハッシュ・テーブル
ハッシュ変数は,配列のインデックスが数値でなくても構わない。

 ハッシュ関数とは,何らかのデータ(ここでは「山梨」)を入力して,ある数値を出力するようなブラック・ボックスだと考えてください(図3)。ハッシュ関数には数値化できるデータなら,何でも入力できます。「山梨」という文字に割り当てられた文字コードから,何らかの数値を出力できます。文字や数値だけでなく,画像や音楽のような音声情報も数値化されているので,同じです。

図3●ハッシュ関数
図3●ハッシュ関数
[画像のクリックで拡大表示]

 ハッシュ関数は,どんな大きさの情報でも入力できます。しかし出力されるのは,そのハッシュ関数で定められた長さに決まっています。

 インターネットでよく使われるハッシュ関数に,MD5とSHA-1があります。MD5では128ビット,SHA-1では160ビット長の数値を出力します。この出力値をハッシュ値といいます。

 一冊の本の中のすべての文字を160ビット長の数値に変換することもできますが,ハッシュ値だけから元のデータを復元することはできません。そのためハッシュ値はダイジェスト(消化物)といわれることもあります。

ハッシュ関数の実験

 Linuxでは,ハッシュ関数はopensslコマンドを使って体験できます。"nikkeiBP"という文字列のハッシュ値をMD5とSHA-1のそれぞれで出力させてみます。


$ echo NikkeiBP|openssl md5
54d080fdcc7498d3165a18ec4894fe05


$ echo NikkeiBP|openssl sha1
27d6b1821fd913a083a792d83a10d1f0b3a89d63

 ここで1文字だけ「P」を「p」に変えてみましょう。


$ echo NikkeiBp|openssl md5
70870ff1c2dfe3ffd8ec9285da56fc48

 すると,1文字だけしか変更していないのに,全く違うハッシュ値が出力されました。

 次に,ファイル全体のハッシュを計算します。ファイルには,パスワードの保存ファイルである/etc/shadowを使います。


$ su
# cat /etc/shadow |openssl md5
61a00b5375930961388c89ddbdcd9f28

 /etc/shadowファイルには,ユーザーのパスワードが暗号化されて格納されています。

 ではここで,passwdコマンドを使って,あるユーザーのパスワードを変更してみます(図4)。

図4●パスワードを変えてみると…
図4●パスワードを変えてみると…
[画像のクリックで拡大表示]


# passwd hata
Changing password for user hata.
New UNIX password:
Retype new UNIX password:passwd: all authentication tokens
updated successfully.

 shadowファイルのハッシュ値を再出力します。


# cat /etc/shadow |openssl md5
ca65d079422437d2d039e6a3d4979a5e

 予想通り,shadowファイルのハッシュ値に変化が見られました。内容が書き換えられたのです。