現金の引き出しなどで使用するキャッシュカードの暗証番号4桁の数値は、通信回線上は素の数値4桁が送られていないのはご存じでしょうか? 例えば、口座番号「9999999」(7桁でカード磁気に内蔵)、暗証番号(入力)が「1111」の4桁だったとすると「1111」というデータが送られるのではなくて「14d40716f59ccdded0d5089da5254aacaeb1596c」という40桁のデータが送られます。「えっ、それで口座と暗証番号の照合ができるの?」という疑問が湧くかもしれませんが、これができるのです。

今日はこのあたりの原理を特集してみたいと思います(実際の運用ではもっと複雑な仕組みですが、説明のため簡素化しています)。

たった1文字でも40桁の文字列の表示になる摩訶不思議

一見、暗証番号の暗号化のようなイメージを持たれるかもしれませんが、この40桁の文字列から、元のデータである口座番号の「9999999」も「1111」も復元できません。数学的に記述すると、次のようになります。

独立変数x=99999991111 従属変数y=f(x)=f(99999991111)=14d40716f59ccdded0d5089da5254aacaeb1596c

与えられたxを関数f(x)に入れると、あるロジックで計算され上記の40桁のデータが出力されます。暗号はx = g(y) = 99999991111が求められますが、上記の関数では復号化ができないという特性があります。

そのためxを求めるには、ひたすらy=f(x)にxを入れていき、14d40716f59ccdded0d5089da5254aacaeb1596cになるxをシミュレーションする以外、xを見つける方法がないのです。

銀行ではオンライン・システムに登録された口座番号と暗証番号から、同じくこの関数f(x)を使って値を出力し、送られてきた40桁の数値と比較して合致していれば、現金引出などの処理を受け付けることになります。

意外と応用されているハッシュ関数

ここで利用される関数f(x)がハッシュ関数といわれるものです。ハッシュ(hash)の本来の意味は「切り刻む」「細切れにする」です。ハッシュ関数から計算される値をハッシュ値といい、上記の例では40桁の値となります。ハッシュ関数にはいろいろな方式があり、ここでは広く使用されているSHA1という40桁の英数文字列にする方式で説明します。元のデータの長さや中身に関係なく40桁の英数文字列で表すという点が特徴です。

従って理論的には、無限に存在する世の中の全てのデータ(あるいはファイル)を40桁で表す訳ですから、「1÷使用する文字コードの種類36の40乗」の確率で同一のハッシュ値に重なることが考えられます。そこで最近では、桁数を増やしたSHA512などが推奨されています。ただ桁数を増やすとCPUの処理時間を要するので、ハードウェアの進化と比例して改善されるというのが現実的なように思えます。

ハッシュ関数を使うことで万一回線から情報が漏えいしても、元の意味を復元することが限りなく困難なため、キャッシュカードの暗証番号という生データをやり取りするのに比べて安全性を高めることができます。また最近では、セキュリティの手段として、Home Pageの改ざん防止対策として、元のデータのハッシュ値を計算しておき、常に直近のWebデータ(画像を含む)のハッシュ値を比較して防御を図るケースもあるようです。

ちなみに弊社でも、システム改ざん対策(Real Time Recovery Solution)を販売しています。

【1文字変化しても全く異なる文字列になる原理】この原理を語れるとお客様から一目置かれるかもしれません

たった1文字だけゼロが1に変化しただけで、ハッシュ値は全く異なるものになります。ここでは例として「00001」と「00000」の場合で簡便的に検証します。

下の図のように、各桁を右の「説明」にあるように計算していくと、それぞれが異なる4桁のコードに変換されます。キーポイントは各桁を横にスライドさせていき非線形の計算式を施すという感じでしょうか。SHA1やMD5などのハッシュ計算方式でも基本的な原理は同じです。

注意:実際のプログラムでは、常数の加算方法や除算の余りなどの設定は異なります(便宜上簡素化して実証しました)。

本記事は、アイ・ユー・ケイが運営するブログ「つぶやきの部屋」を転載したものになります。

(マイナビニュース広告企画:提供 アイ・ユー・ケイ)

[PR]提供: