Copyright © 2000-2005 eazyfox. All Rights Reserved.
HOME| Firewall | Security| 製品紹介| SecuTool| Forest| Hello| Link| 掲示板| 雑談掲示板| SiteMap| Contact

・暗号化

コンピュータとネットワークが仕事や日常生活に欠かせないインフラとなった現在、格納されているデータやネットワーク上を流れるデータが外部から覗かれたり、盗聴されるケースが多くなっている。これは決して企業や政府の機密情報だけに当てはまることではない。日ごろ家族や友人との間でやり取りするメールやIP電話でも同じことである。

そこで見られたくない情報の機密性を守るために「データの暗号化」を行う必要がある。今では持ち運びするノートPCではセキュリティ対策(データの暗号化)は必須になっているし、企業ではどのようなデータであれ、業務に関するデータを暗号化せずに持ち歩くことは「危険な行為」とみなされている。

では現在良く用いられている暗号化はどのようなものなのかを見ていこう。

銀行など金融機関のサイトで振込みや残高の照会をブラウザで行うとき SSL
会社のネットワークに自宅や公衆回線から接続するとき IPsec
メールの本文や添付ファイルを暗号化して送るとき PGP・S/MIME
無線LANに接続して社内の共有ファイルサーバにアクセスするとき WEP・TKIP
ノートPC内に保存した重要な機密データを暗号化して保存するとき AES・PGP

古くからメールの内容は通常暗号化されない(普通のテキストで転送される)ことがインターネットユーザの常識であったため、「重要な内容や機密データは電話とFAXを使こと」と決めている会社もあった。しかしインターネットが一般化してメールが仕事を進める上で不可欠なものになってくると「FAXで」とは言えなくなってしまった。

では暗号化の仕組みとメールの内容を暗号化するPGPの仕組みを見ることにしよう。

注意:暗号化とはデータを他の人にわからない符号化データにすることで、当然反対の符号化データを元のデータに戻すことが必要で、それを復号化と呼ぶ。ここでは暗号化・復号化を合わせて「暗号化」と呼ぶことにする

暗号化とは

暗号化に必要なものは次の3つである。

つまり 

暗号化したテキスト・データ = 暗号化エンジン(暗号化のキー , 暗号化の対象テキスト・データ)

となる。つまり暗号化したデータは暗号化エンジンでキーと元になるデータから演算した結果ということだ。

暗号化エンジン(暗号器)の基本的な動作は

置換 文字・データを別の文字・データに置き換える
転置 決まった規則で文字・データの入れ替え(並び替え)を行う

古来の暗号では「置換」するのに乱数表や歯車をつかっていたが、コンピュータの世界では計算による結果で置換する。また転置も古来は文字単位であったが、現在では文字以外のデータの方が多いので複数のビットをブロックとして扱い置換する。

実際の暗号化の方法の説明として、現在では使われなくなったが最もよく普及したDES(Data Encryption Standard)の方法を見てみる。

左図は"Data Encryption Standard", Federal Information Processing Standards Publication 46-3, 1999から借用してきたDESの動作の図である。

まず最初にテキストやデータを64ビット(英数字なら8ビットなので8文字、漢字なら4文字)ごとに区切って1ブロックとする。その1ブロックを半分にして右(R)と左(L)に分ける。

次に右半分を暗号化キー(K1)で暗号化したデータを作成する。K1は暗号化キーのKから生成した副キーである。

暗号化した右(R)データと元のままの左(L)をXOR(排他的論理和)演算を行う
最後に右(R)と左(L)を入れ替える。これが1回分の処理。

つまり1回の処理結果は
L1=R0
R1=L0 XOR f(R0,K1)
となる。
DESではこれを16回繰り返した結果がOutputになる。

これ以上難しい説明は筆者には出来ないので図の元であるPDFなどを参照して欲しい。

要するに元になるデータを規則に従って攪拌することが暗号化である。当然元に戻すことが出来なければ意味がない。

またDESのキー長は現在では少なすぎる56ビットである。現在では最低でも128ビットのキー長が求められるが、56ビットでも考えられるキーの数は2の56乗で、72,057,594,037,927,936パターンである。人力では解析不可能な数だし、DESが制定された当時(1977年)では十分に堅牢な暗号だった。

現在ではDESに変わってAESが標準暗号化方式として制定されてる。

共通鍵と公開鍵

暗号化でややこしいのは2つの方法があるということである。それは一つの秘密にした鍵を送信元と受信先で使う共通鍵方式と、公にされた公開鍵と秘密にしておく秘密鍵を使う公開鍵方式である。ちょっと用語を整理しておくと

共通鍵方式 秘密鍵 対称暗号
公開鍵方式 公開鍵+秘密鍵 非対称暗号

2つの方法だが、言い方は3パターンあるので、余計に難しく思えるが理由がわかると簡単だ。

共通鍵方式 秘密の鍵を使って暗号化する。暗号データの受取人は送信者と同じ秘密の鍵を使って元のデータに戻す。つまり同じ鍵を使って暗号化して、暗号化とは逆の計算で元のデータに戻す。
公開鍵方式 送信者は送信者の秘密鍵を使って暗号化し、受信者は送信者の公開鍵を使って元に戻す。または送信者は受信者の公開鍵を使って暗号化し、受信者は受信者の秘密鍵を使って元に戻す。元に戻すときの計算は暗号化するときの計算の逆算ではない

これが1つの(共通の)秘密鍵を使った暗号化と、2つの(ペアの)公開鍵と秘密鍵を使う暗号化の違いである。

昔から暗号化するのに置換表(乱数表)を使ったものは、同じ乱数表を使って元に戻した。置換表が外部に漏れると暗号がばれてしまうというものである。これが秘密鍵方式だ。

外部に漏れるとだめになる置換表(秘密鍵)を安全に相手に渡すことや、相手ごとの秘密鍵を管理しておくのは大変な作業である。そこで公開鍵方式が出てきた。

公開鍵と秘密鍵

公開鍵は誰に渡しても良い(公開しておく鍵)である。秘密鍵で暗号化されたデータはペアとなる公開鍵だけで元に戻すことが出来る。または公開鍵で暗号化されたデータは秘密鍵だけで元に戻せる。この組み合わせを使いわけると

秘密鍵で暗号+公開鍵で元に戻す 暗号化した人(送信者)は秘密鍵を持っている人だと断定できる
公開鍵で暗号化+秘密鍵で元に戻す 元に戻せるのはペアの秘密鍵を持っている人だけである

つまり送信した人を特定する目的だと(送信者の)秘密鍵で暗号化、受信者にしか判らないように暗号化するには(受信者の)公開鍵で暗号化するのである。

暗号化によってデータやテキストの内容が他人に盗聴されることがなくなるのと同時に「メールを送った人、データを作成した人を特定すること」が可能となる。つまり偽者メールが判定できるということだ。

メールを暗号化して他人に見られないようにする 受信者の公開鍵で暗号化する 受信者の秘密鍵が無いと暗号は元に戻らない
メールを送信した人を特定する 送信者の秘密鍵で暗号化する 送信者の秘密鍵で暗号化されたメール以外は送信者が入手した公開鍵で元に戻せない

またメッセージ承認機能(メッセージダイジェスト)と組み合わせることで、データやテキストの内容が誰かに書き換えられる事を防ぐことも可能となる。

もう一つ大切なことは秘密鍵方式で問題となった「安全な鍵の管理」が公開鍵方式では楽になることである。秘密鍵方式では相手ごとの鍵を厳重に保管しておく必要があったが、公開鍵方式では自分自身の秘密鍵1つだけを管理しておけばよい、だれかの公開鍵はいつでも必要なときに入手できるから、管理に気を使う必要はない。

メールの相手が10人いれば10個の鍵を管理する必要があった秘密鍵方式と比較して、1つの秘密鍵を管理すればよい公開鍵方式のほうが利便性が良いのは明らかだ。

PGPを使ったメール

暗号化の代表的なツールであるPGPはPhilip Zimmermannが作成したが、製品自体は紆余曲折があり、現在ではGNUライセンスのものやPGPコーポレーションの有償製品などいろいろなものがある。PGPの入手や設定方法については検索エンジンで「PGP」、「OpenPGP」で探してもらえればたくさん出てくるので、そちらを参照していただきたい。

PGPでは公開鍵と秘密鍵の2つを用いる「公開鍵暗号方式」をとっている。

公開鍵 誰でも入手可能な公開されている鍵。公開鍵サーバから入手する
秘密鍵 本人が大切に保管しておく秘密鍵。公開鍵で暗号化されたメールは秘密鍵が無いと元に戻らない

公開鍵サーバはhttp://pgp.nic.ad.jp/pgp/などたくさんある。ここから相手の公開鍵を入手する。メール送受信の手順は次のようになる。

まずBさんがAさんに暗号化メールを送るときの場合(Aさんは受信者、Bさんは送信者)

  1. BさんはAさんの公開鍵を入手して、Aさんに送るメールの本文を作成する
  2. メール本文をAさんの公開鍵を使って暗号化する(正確にはメールは圧縮されて使い捨て鍵という一時的な鍵で暗号化して、その鍵を公開鍵で暗号化する。つまりメール本文は"使い捨て鍵で暗号化された圧縮メール+公開鍵で暗号化された使い捨て鍵"となる)
  3. 暗号化されたメールをAさんに送信する。これは通常のメールを送信するのと同じ
  4. メールを受け取ったAさんはAさんの秘密鍵を使ってメールを復号化する(これも使い捨て鍵を秘密鍵を使って復号化して、その復号された使い捨て鍵でメール本文の復号を行う)
  5. 復号化され元に戻ったメールを読む

これで平文だったメール本文は暗号化されて送られ、Aさんが持つ秘密鍵で復号化されて始めて普通の平文になる。このためAさん以外に読まれたり、途中で誰かに改ざんされることはなくなる。

また筆者がAさんに送るメールを送るときに確実に筆者が書いたものだと断定できるように電子署名としても使うことができる。これは筆者の名前を騙って誰かがAさんにメールを送っても筆者が書いたものかとうか確認するためのものだ。

  1. Aさんは筆者の公開鍵を入手する
  2. Aさんに送るメールを作成する
  3. メール本文を筆者の秘密鍵を使って暗号化する
  4. 暗号化されたメールをAさんに送信する。これは通常のメールを送信するのと同じ
  5. メールを受け取ったAさんは筆者の公開鍵を使ってメールを復号化する
  6. 復号化されたら筆者の書いたものなので元に戻ったメールをよむ。もし筆者以外の人間が書いていれば復号はできない

このようにしてメール内容の保護と保証が可能となる。今後電子メールが絡んだ問題が大きくなってくることが予想されるので、こういった暗号化や電子署名の重要性が大きくなってくることは間違いないだろう。

またPGPはDiskのデータの暗号化も可能となっている。これで侵入してきたクラッカーに大切なデータを見られることも無くなるし、自分以外に秘密にしておきたい文章やメールを見られることも防ぐことが出来る。

メッセージ認証

メールは暗号化により送信者が特定できることを述べた。もう一つの機能としてメールの内容が書き換えられていないことを証明する改ざん防止がある。これはメッセージ認証、電子署名、メッセージダイジェストといろいろ呼び方があるが、ここではメッセージ認証と呼ぶことにする。

メッセージ認証に必要な機能はメッセージダイジェストと呼ばれるものをメッセージに付加することで実現している。メッセージダイジェストとは

メールや画像などの可変長データから計算されるある決まった数値

のことである。メッセージダイジェストに求められる機能は

  1. どのような長さのデータでも一定の長さの数値データが算出されること
  2. 算出された数値から元の値が推測できないこと ・・・One Way
  3. データのごく一部が書き換えられても数値が変わること
  4. 同じ数値になることが極めて少ないこと(同じ値になることが無いこと) ・・・Collision-Free
  5. 計算に要する時間と負荷が出来るだけ小さいこと

重要なことは2.の逆算が不可能なことと、3.の異なるデータでも同じ数値になることが無いことである。これはメールの書き換えが行われたとき、同じ数値になったのでは書き換えられたかの判断が出来なくなる。メッセージダイジェストは現在SHA(Secure Hash Algorithm)系とMD5(Message Digest)系が標準である。

このように可変長のデータから一定のデータを作成するものを「ハッシュ関数(Hash Function)」と呼んでいる。2.の求めた数値から元の値を算出できないものを一方向ハッシュ関数(One way Hash Function)と呼ぶ。同様に求められた数値をハッシュ値と呼ぶ。

MD5の算出方法を参考までに見ておこう。RFC1321に詳しい説明があるので参考にして欲しい。

STEP1 0ビット以上のデータを用意し、データを512ビットごとのブロックに分割する。最後のブロックが448ビットに足りないときはビットを付け足す
STEP2 STEP1で作ったデータに元のデータの長さを64ビットで付け加える。これで全てのブロックが512ビットになる
STEP3 A,B,C,Dの4つの32ビット計算領域を用意する。各領域は
 A:01 23 45 67
 B:89 ab cd ef
 C:fe dc ba 98
 D:76 54 32 10
の値で初期化する
STEP4 まず初めに関数を4つ定義する(X,Y,Zの32ビットワードを変数とした32ビット出力の関数)
 (1) F(X,Y,Z) = XY v not(X) Z ・・・ (X and Y) or (not(X) and Y)
 (2) G(X,Y,Z) = XZ v Y not(Z) ・・・ (X and Z) or (Y and not(Z))
 (3) H(X,Y,Z) = X xor Y xor Z ・・・ (X xor Y xor Z)
 (4) I(X,Y,Z) = Y xor (X v not(Z)) ・・・ (Y xor (X or not(Z)))

次に64個のテーブルを用意する。各テーブルの要素は
テーブル[i] = (2^32 * 絶対値(sin(i)))の整数部

そして512ビットごとに順に計算を行う
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)として
    [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]・・・・
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)として
    [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]・・・・
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)として
    [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]・・・・
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)として
    [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]・・・・

最後に元の値を加える
STEP5 生成されたメッセージダイジェストはA,B,C,Dとなる

MD5は現在では同じ数値になるデータを作ることが可能であることが証明されているが、「同じ数値になることが極めて少ない」ということには変わりが無い。しかし悪意を持ってデータを改ざんして元のデータと同じ数値にできる可能性があるのであればメッセージダイジェストとしての機能を果たすことはできないというのがセキュリティの世界での共通認識である。

メッセージ認証は上記のようにハッシュ値を求め、元のメッセージと一緒に相手先に送付する。このときハッシュ値を送信者の秘密鍵で暗号化しておく。メッセージは平文のままでよい(公開鍵暗号方式の場合)。

受信者は
 (1) 受信したメッセージからハッシュ値を算出する
 (2) 送信者の公開鍵で送られたハッシュ値を復号する
 (3) 算出したハッシュ値と復号したハッシュ値を比較する

これでハッシュ値が一致するということは
 ・送信者の公開鍵で復号できたので送信者が特定できる
 ・ハッシュ値が一致したのでメッセージに改変が無いことがわかる

となって送信者とメッセージの正しさが証明されるということである。
ハッシュ値が復号できなければ送信者が違う、ハッシュ値が異なればメッセージが改変されているということになる。

また共通鍵暗号方式では共通鍵と固定文字列の排他的論理和を算出し、算出値とメッセージのハッシュ値HMAC(鍵ハッシュメッセージ認証コード)をメッセージに付けて送付する方法があります。

このような方法でメッセージの送信者とメッセージの内容が正しいと証明できること(メッセージの完全性が確認できること)がメッセージ認証となります。

メッセージダイジェストの応用

Personal FirewallやAnti-Virusなどでファイルが改変(更新)されたことを検出するのにメッセージダイジェストが使われます。ハッシュ値を計算する処理は負荷も軽く速いので、改変を見つけるのにたいへん都合がよいからです。

あらかじめハッシュ値を計算して記録しておくと、以降OSがファイルにアクセスするときにハッシュ値の再計算を行って記録したハッシュ値との比較を行い、異なれば改変ありとなります。

またLinux系のファイルをDownloadするときにMD5のチェックサムデータも同時にDownloadしてファイルが改変されたり、Downloadの途中で壊れていないかをチェックすることができます。

セキュリティのTopに戻る