Perlモジュールで暗号化 - Digest::SHA1編
最近では、MD5も次第に研究されてきて、いろいろと弱点も指摘されているようです。
そこで、当然ながら他の暗号方式も考案されてきました。
その1つが、SHA-1(エスエイチエー、Secure Hash Algorithm)です。 MD5方式に比べて、攻撃に強いとされています。
その1つが、SHA-1(エスエイチエー、Secure Hash Algorithm)です。 MD5方式に比べて、攻撃に強いとされています。
そのSHA-1アルゴリズムへのPerlインターフェースとして、Digest::SHA1モジュールがあります。
7-1. デモ
Digest::SHA1のデモです。文字列をSHA-1形式で変換します。
7-2. Digest::SHA1モジュール
Digest::SHA-1モジュールも、Digest::MD5と同様に標準モジュールとして採用されています。
データ長は、バイナリ形式では20ビットで、hex形式で40文字、Base64形式で27文字となります。
データ長は、バイナリ形式では20ビットで、hex形式で40文字、Base64形式で27文字となります。
基本構文は次のとおりです。Digest::MD5とほぼ同じであることが分かります。
関数形式 |
|
||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
OO形式 |
|
コード例は次のとおりです。
01 | use strict; |
02 |
03 | # モジュールを宣言 |
04 | use Digest::SHA1 qw(sha1_hex); |
05 |
06 | # 文字列 |
07 | my $str = 'abcd' ; |
08 |
09 | # MD5変換(hex形式) |
10 | my $digest = sha1_hex( $str ); |
11 | print "$digest\n" ; |
1 | > 81fe8bfe87576c3ecb22426f8e57847382917acf |
hex形式で、上記のとおり40文字で出力されました。
ここで、MD5形式との特徴を確認しておきましょう。一般的に、データ長が長いほど、強度が強いということが言えます。
データ長 | hex表記 | Base64表記 | |
---|---|---|---|
SHA-1 | 20ビット | 40文字 | 27文字 |
MD5 | 16ビット | 32文字 | 22文字 |
7-3. 暗号として使うには
Digest::SHA-1を暗号ツールとして利用する場合は、第5章の使い方と同じです。
saltをランダムな8文字としたコード例です。
saltをランダムな8文字としたコード例です。
01 | use strict; |
02 |
03 | # モジュールを宣言 |
04 | use Digest::SHA1 qw(sha1_hex); |
05 |
06 | # 文字列 |
07 | my $passwd = '1234' ; |
08 |
09 | # saltの8文字を16進法式でアトランダムに生成 |
10 | my @str = ( 'a' .. 'f' , 0 .. 9); |
11 | my $salt ; |
12 | for (1 .. 8) { |
13 | $salt .= $str [ int ( rand ( @str ))]; |
14 | } |
15 |
16 | # SHA1変換(hex形式) |
17 | my $digest = $salt . sha1_hex( $salt . $passwd ); |
18 | print "$digest\n" ; |
1 | > 81fe8bfe87576c3ecb22426f8e57847382917acf |
次に、照合処理です。
暗号文字の先頭の8文字を抜き出し、SHA-1(hex) 変換して、照合することになります。
暗号文字の先頭の8文字を抜き出し、SHA-1(hex) 変換して、照合することになります。
01 | use strict; |
02 |
03 | # モジュールを宣言 |
04 | use Digest::SHA1 qw(sha1_hex); |
05 |
06 | # パスワード |
07 | my $passwd = '1234' ; |
08 |
09 | # 暗号文字 |
10 | my $crypt = '81fe8bfe87576c3ecb22426f8e57847382917acf' ; |
11 |
12 | # saltは先頭の8文字を抜き出す |
13 | my $salt = substr ( $crypt , 0, 8); |
14 |
15 | # 判定 |
16 | if ( $crypt eq ( $salt . sha1_hex( $salt . $passwd ))) { |
17 | print "OK\n" ; |
18 | } else { |
19 | print "NG\n" ; |
20 | } |
1 | > OK |
上記の暗号/照合コードをサブルーチン化すると、次のようになります(hex形式の場合)。
01 | use strict; |
02 |
03 | # モジュールを宣言 |
04 | use Digest::SHA1 qw(sha1_hex); |
05 |
06 | # 文字列 |
07 | my $passwd = '1234' ; |
08 |
09 | # 暗号 |
10 | my $crypt = &encrypt( $passwd ); |
11 | print "$crypt\n" ; |
12 |
13 | # 照合 |
14 | if (&decrypt( $crypt , $passwd )) { |
15 | print "OK\n" ; |
16 | } else { |
17 | print "NG\n" ; |
18 | } |
19 |
20 | #----------------------------------------------------------- |
21 | # Digest::SHA-1 (hex) 暗号化 |
22 | #----------------------------------------------------------- |
23 | sub encrypt { |
24 | my $plain = shift ; |
25 |
26 | # saltの8文字を16進でアトランダムに生成 |
27 | my @str = ( 'a' .. 'f' , 0 .. 9); |
28 | my $salt ; |
29 | for (1 .. 8) { |
30 | $salt .= $str [ int ( rand ( @str ))]; |
31 | } |
32 |
33 | # MD5変換(hex形式) |
34 | return $salt . sha1_hex( $salt . $passwd ); |
35 | } |
36 |
37 | #----------------------------------------------------------- |
38 | # Digest::SHA-1 (hex) 照合 |
39 | #----------------------------------------------------------- |
40 | sub decrypt { |
41 | my ( $crypt , $plain ) = @_ ; |
42 |
43 | # saltは先頭の8文字を抜き出す |
44 | my $salt = substr ( $crypt , 0, 8); |
45 |
46 | # 照合 |
47 | return $crypt eq ( $salt . sha1_hex( $salt . $plain )) ? 1 : 0; |
48 | } |
1 | > 3e24ac81e6ea852cefd4b7d75496dad4a5ab5bead9669e18 |
2 | > OK |
7-4. 暗号/照合コード(Base64出力)
Base64形式出力の場合は、次のように記述することができます。
01 | use strict; |
02 |
03 | # モジュールを宣言 |
04 | use Digest::SHA1 qw(sha1_base64); |
05 |
06 | # 文字列 |
07 | my $passwd = '1234' ; |
08 |
09 | # 暗号 |
10 | my $crypt = &encrypt( $passwd ); |
11 | print "$crypt\n" ; |
12 |
13 | # 照合 |
14 | if (&decrypt( $crypt , $passwd )) { |
15 | print "OK\n" ; |
16 | } else { |
17 | print "NG\n" ; |
18 | } |
19 |
20 | #----------------------------------------------------------- |
21 | # Digest::SHA-1 (Base64) 暗号化 |
22 | #----------------------------------------------------------- |
23 | sub encrypt { |
24 | my $plain = shift ; |
25 |
26 | # saltの8文字をアトランダムに生成 |
27 | my @str = (0 .. 9, 'a' .. 'z' , 'A' .. 'Z' , '+' , '/' ); |
28 | my $salt ; |
29 | for (1 .. 8) { |
30 | $salt .= $str [ int ( rand ( @str ))]; |
31 | } |
32 |
33 | # MD5変換(hex形式) |
34 | return $salt . sha1_base64( $salt . $passwd ); |
35 | } |
36 |
37 | #----------------------------------------------------------- |
38 | # Digest::SHA-1 (Base64) 照合 |
39 | #----------------------------------------------------------- |
40 | sub decrypt { |
41 | my ( $crypt , $plain ) = @_ ; |
42 |
43 | # saltは先頭の8文字を抜き出す |
44 | my $salt = substr ( $crypt , 0, 8); |
45 |
46 | # 照合 |
47 | return $crypt eq ( $salt . sha1_base64( $salt . $plain )) ? 1 : 0; |
48 | } |
1 | > +SWsMrVFyRMbrKxsIE6QIlJz62X9wzidvzk |
2 | > OK |