2009年4月12日日曜日

パスワードを暗号化してみよう


パスワードを暗号化してみよう

| 1. PERLでの暗号化の仕組み | 2. 暗号化の関数 | 3. 認証する方法 |
| 演習問題

 テーマ  ホームページは不特定多数のユーザーが見ることがきるものであるし、 また見えないと意味がない。 しかし、特定のユーザーにだけしか見せたくない場合は、 パスワードを設定する必要が出てくる。
そこで、パスワードをPERLでどのように暗号化したらよいかを覚えておこう。 すなわち、入力されたパスワードのエンコード( encode :暗号化)、 そしてデコード( decode :平文化、要するにもとの文にもどす)について、 PERLでどのように実現するかということである。

 戦略 
------------------------------------>

1. PERLでの暗号化の仕組み

パスワードが入力されたとして、 このパスワードが正規ユーザーのものであるかどうかを どのように判断すればよいのであろうか?
パスワードそのものをファイルに保存しておけばよさそうだが、 これではリスクが大きすぎる。
なぜなら、パスワードのファイルを見られた時点で終わりだからである。 では、どうすればよいか?
必要とされる準備は、 パスワードを暗号化した文字列をファイルとして保存しておくことである。 こうしておけば、 パスワードが入力されたとき、 このパスワードを暗号化し、 保存してある暗号化された文字列と合致するかどうかをチェックすればよい。 合致すれば正規ユーザーとして認証され、 合致しなければ不正ユーザーと認識される。
では、 パスワードのファイルを見られたときはどうであろうか? 保存してあるのは暗号化されたパスワードであるので、 不正ユーザーはこれを解読してもとのパスワードにもどさなければ、 正規のパスワードを得ることはできない。
したがって、 ここで使用する暗号化アルゴリズムが安全なものであれば、 このパスワードシステムも安全といえる。

パスワードの登録・変更、 パスワードの認証は以下のような流れになる。

パスワードの登録・変更

パスワードの入力
−−−>
暗号化
−−−>
ファイルに保存

パスワードの認証

パスワードの入力
−−−>
暗号化
−−−>
ファイルに保存されている暗号化パスワードと照合


2. 暗号化の関数

暗号化のために、 PERLでは crypt という関数が用意されている。

crypt関数 の書式は以下のようになる。

     crypt( 入力されたパスワード,2文字のキー)     


ここで、2文字のキーとは、 暗号化するときの初期値であり、

a-z A-Z 0-9 /

の合計64(= 26 + 26 + 10 + 2)文字を任意に指定できる。

crypt関数 により、パスワードは NBS Data Encryption Standard(DES) というアルゴリズムによって暗号化される。

DESにより暗号化されたパスワードは、 解読することが事実上不可能である。 正確には、解読することは可能であるが、 現在のコンピュータの速度では膨大な時間が必要で、 事実上解読できなということである。
このような事実上逆変換ができない一方通行の関数を一方向性関数という。 DESはこの一方向性関数なのである。
しかし、 将来的には、コンピュータの演算速度が飛躍的に増大するので、 現在の暗号技術ではいずれ解読可能となることであるとも言える。

では、以下の具体例で考えてみよう。

次表の条件で暗号化してみよう。

パスワード BayStars
2文字のキー AB


暗号化するには、

     $encoded_pwd = crypt("BayStars", "AB")     

のように書けばよい。

こうすると、暗号化された文字列として $encoded_pwd には、 ABA.eeONdAiM. が得られる。

すなわち、

   1)  2)  3)  4)  5)  

   #!/usr/local/bin/perl  $input_pwd = "BayStars";  $salt = "AB";  $encoded_pwd = crypt($input_pwd, $salt);  print "$input_pwd ---> $encoded_pwd\n";  

を実行すると、

     BayStars ---> ABA.eeONdAiM.     

という結果が得られるであろう。

パスワード BayStars から生成された暗号文をよく見てみよう。
先頭の2文字が AB となっていることに気付くであろう。 これらはキーに設定した2文字である。 このように暗号文の先頭には設定した2文字のキーがついて、 その後に11文字の暗号化された文字が並ぶのである。

ところで、もとのパスワード BayStars が8文字あったので、 生成された暗号文が2文字のキーと11文字になったのではないかと考えるかもしれないが、 実は何文字のパスワードを入力しても同じなのである。

そこで、同じプログラムを使って、 Giants という6文字を暗号化してみよう。
結果は、

     Giants ---> AB7teWSKDWa/A     

というように、やはり11文字である。

さらに、 BayStarsGiantsDragonsCarpSwallows と長い文字列を暗号化しても、

     BayStarsGiantsDragonsCarpSwallows ---> ABA.eeONdAiM.     

と、結果は11文字になる。
この場合 BayStars と入力した場合と同じ結果になる。 なぜか?
理由は簡単で、 調べてみるとよく分かることであるが、 パスワードとして有効なのは8文字までだからである。
BayStars の後ろに何文字追加しても暗号化された文字列は同じになる。

3. 認証する方法

さて、これで暗号化はできることになったが、 この暗号文を利用して認証するにはどうすればよいのだろうか?

前述したように、 入力されたパスワードを暗号化して、 保存してある暗号文を照合すればよいのである。

したがって、認証時にも crypt 関数を使うことになる。

ただし、 暗号文の先頭の2文字のキーを合わせなければならないので、 暗号文の先頭の2文字を取り出して、 これをキーとする。

このためには、以下の書式の substr関数 を利用する。

     substr(文字列,取り出す最初の文字の位置,取り出す文字数)     

ここで、取り出すのは先頭の2文字なので、

     substr(暗号文,0,2)     

とすれば、暗号文の先頭の2文字を取り出せる。
こうして取り出した2文字をキーとして crypt関数 で使ってやればよい。

したがって、次のように書けば、 入力されたパスワードを保存された暗号文と照合するための、 対応した暗号化ができる。

     crypt(パスワード,substr(登録されているパスワードの暗号文,0,2))     

BayStars で暗号化したものと照合をしてみよう。

プログラムは以下のようになる。

   1)  2)  3)  4)  5)  6)  7)  8)  9)  10)  11)  12)  13)  14)  

   #!/usr/local/bin/perl  $old_pwd = "BayStars";  $salt = "AB";  $encoded_pwd = crypt($old_pwd, $salt);  print "$old_pwd ---> $encoded_pwd\n";    print "Password : ";  $input_pwd = <STDIN>;  chop($input_pwd);  if(crypt($input_pwd, substr($encoded_pwd, 0, 2)) eq $encoded_pwd){  print "Password accepted.\n";  } else {  print "Not accepted\n";  }  


演習問題

演習1 最後の例をHTMLにしてみよう。 これをHTMLにした例は、 こちら のようになる。
演習2 crypt関数 のキーを別の文字に変更して、 結果を調べてみよう。

CRYPT関数の例

Posted via web from realtime24's posterous

0 件のコメント:

銀行株

Only Wire

    フォロー