• 締切済み

暗号・復号 cgiスクリプトについて

こんにちは。 私はcgiスクリプトにて文字を暗号化させたいと思っています。 友人に暗号化復号化スクリプトを書いてもらったのですが どうやって動かすかよくわかりません。 http://www.rescue.ne.jp/cgi/htpasswd/makepwd-des/ 上記のサイトのように出力させたいのですが、スクリプトだけでは私には難しいです。 その友人は海外に行ってしまい連絡が今は取れないんです。 sub enc_string{ my ($key, $string) = @_; my @map = (('A' ... 'Z'), ('a' ... 'z'), ('0' ... '9'), '+', '&'); my @key = unpack('C*', $key); my $str = ''; my @x = map { int(rand(200)) } (0 ... 2); @key = map {$x[$_] ^ $key[$_]} (0 ... 2); while($string ne ''){ my $n = substr($string, 0, 3, ''); my @n = unpack('C3', $n); map{$n[$_] ^= ($key[$_])} (0 ... 2); @key = unpack('C3', $n); @key = map {$x[$_] ^ $key[$_]} (0 ... 2); my $a = $n[0] >> 2; my $b = (($n[0] & 3) << 4) | ($n[1] >> 4); my $c = (($n[1] & 15) << 2) | ($n[2] >> 6); my $d = $n[2] & 63; $str .= $map[$a] . $map[$b] . $map[$c] . $map[$d]; } my $a = $x[0] >> 2; my $b = (($x[0] & 3) << 4) | ($x[1] >> 4); my $c = (($x[1] & 15) << 2) | ($x[2] >> 6); my $d = $x[2] & 63; return $str.'<>'.$map[$a].$map[$b].$map[$c].$map[$d]; } このスクリプトで暗号するようですが、初心者なものでどうやって 手直し?追加すればよいのでしょうか? #!/usr/bin/perlを最初に入れるのはわかります。 あとこのスクリプトの他に復号、MD5にて暗号のスクリプトがあります。 まずは暗号化させてみたいのですが、よろしくお願いします

みんなの回答

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

>このスクリプトで暗号化、復号化をすることはできるのでしょうか? できますよ。 enc_string にパスワードと元の文字列を渡せば暗号化された文字列が返ってきます。 元に戻すには dec_string にパスワードと暗号化された文字列を渡せばよいです。 元の文字列が hello, world パスワードが xyz とするとenc_stringが返すのは BowtEpp7Woh4RIsw<>FpA7 となります。 先の回答に書いたように<>とその後ろのものは暗号化の結果ではなくて その部分を取り除いた BowtEpp7Woh4RIsw が暗号化されたものです。 dec_string にこの BowtEpp7Woh4RIsw と パスワードの xyz を渡すと元の hello, world に戻ります。 BowtEpp7Woh4RIsw<>FpA7 を渡しても、末尾の6文字は勝手に削ってから処理してくれるので 元には戻ります。 一応注意しておくと、それほど強力な暗号ではないようなので 重要なものを隠すために使うのはよく考えてからにしましょう。

kainads
質問者

補足

返答ありがとうございます、もう少しで解決しそうです。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

MD5がちょっとよくわからないけどこんな感じでしょうか。 あ、念のため書いておくとMD5は暗号化じゃないです。逆方向の変換できませんから。 my $original_str = 'hello, world'; say $original_str; say "encrypt"; my $crypt_key = 'xyz'; my $crypted = enc_string($crypt_key, $original_str); say $crypted; say "decrypt"; my $result = dec_string($crypt_key, $crypted); say $result; $crypted =~ s/<>.$//; say dec_string($crypt_key, $crypted); say "md5 : ", encrypt('hello, world', 'sa'); 出力結果を見るとわかるとおり、enc_string の返す結果の末尾に <>とそれに続いて4文字来るのですが、これは暗号化の結果とは関係ありません が、解読の手がかりになったりするので付加情報が着いていると書いたわけです。 hello, world encrypt BowtEpp7Woh4RIsw<>FpA7 decrypt hello, world hello, world md5 : KKrF3p/jmQLX6dJPQGXW1/

kainads
質問者

補足

おはようございます。 このスクリプトで暗号化、復号化をすることはできるのでしょうか? フリーのサーバーでcrypt.cgi(たとえ)のように動かし、文字を暗号化、復号化させたいです。 その為にはこの暗号、復号スクリプトだけでは私には理解できませんし、動かすこともできません。 その知り合いには詳細を教えてもらえないので手詰まりです。 暗号、復号ができるようなスクリプトが使いたいです。 意味不明かもしれませんが、私にとってはとても重要な事でして 何卒サーバーで動くスクリプトをお願いします。 少々時間がかかっても全然問題ありません、他で頼る場所がないのです。 MD5に関しては少々勘違いをしていたようです、もっと別なところで使用されていたみたいです。 よろしくお願いします。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

use strict; use warnings; use feature ':5.10'; sub enc_string{ my ($key, $string) = @_; my @map = (('A' ... 'Z'), ('a' ... 'z'), ('0' ... '9'), '+', '&'); my @key = unpack('C*', $key); my $str = ''; my @x = map { int(rand(200)) } (0 ... 2); @key = map {$x[$_] ^ $key[$_]} (0 ... 2); while($string ne ''){ my $n = substr($string, 0, 3, ''); my @n = unpack('C3', $n); map{$n[$_] ^= ($key[$_])} (0 ... 2); @key = unpack('C3', $n); @key = map {$x[$_] ^ $key[$_]} (0 ... 2); my $a = $n[0] >> 2; my $b = (($n[0] & 3) << 4) | ($n[1] >> 4); my $c = (($n[1] & 15) << 2) | ($n[2] >> 6); my $d = $n[2] & 63; $str .= $map[$a] . $map[$b] . $map[$c] . $map[$d]; } my $a = $x[0] >> 2; my $b = (($x[0] & 3) << 4) | ($x[1] >> 4); my $c = (($x[1] & 15) << 2) | ($x[2] >> 6); my $d = $x[2] & 63; return $str.'<>'.$map[$a].$map[$b].$map[$c].$map[$d]; } say enc_string('xyz', 'hello, world'); 結果: jTeGmSHQ0TPTzzCb<>nSuQ 面倒なのでロジックは追いかけてないけど、サブルーチンの返している文字列には 付加情報が着いてる。 何に使う暗号だか知らないけど、使い方も制限事項もわかってないものを 使うべきではないと思います。

kainads
質問者

補足

返答ありがとうございます。 付加情報が付いているという事はまだ何か足りないという事なのでしょうか? 初心者で無理を承知で質問をしています。 ただ友人からいただいたスクリプトで暗号・復号をしたいだけなのです すみませんがよろしくお願いします。 フリー等のサーバーでcgiとして動けば満足です。 よろしくお願いします。 復号、MD5スクリプトも貼ります # 文字を復号化 sub dec_string{ my ($key, $string) = @_; my $str = ''; if($string =~ s/^<>//){ my @key = unpack('C*', $key); while($string ne ''){ my $n = substr($string, 0, 4, ''); $n =~ tr/A-Za-z0-9\+\&/\x00-\x40/; my @n = unpack('C4', $n); my $a = ($n[0] << 2) | ($n[1] >> 4) ^ $key[0]; my $b = (($n[1] & 15) << 4) | ($n[2] >> 2) ^ $key[1]; my $c = (($n[2] & 3) << 6) | $n[3] ^ $key[2]; $str .= pack('C3', $a, $b, $c); } $str =~ s/[\x00]*$//; return $str; } elsif($string =~ s/<>(.{4})$//){ my $n = $1; $n =~ tr/A-Za-z0-9\+\&/\x00-\x40/; my @key = unpack('C*', $key); @x = unpack('C4', $n); $x[0] = ($x[0] << 2) | ($x[1] >> 4); $x[1] = (($x[1] & 15) << 4) | ($x[2] >> 2); $x[2] = (($x[2] & 3) << 6) | $x[3]; @key = map {$x[$_] ^ $key[$_]} (0 ... 2); while($string ne ''){ my $n = substr($string, 0, 4, ''); $n =~ tr/A-Za-z0-9\+\&/\x00-\x40/; my @n = unpack('C4', $n); my $a = ($n[0] << 2) | ($n[1] >> 4) ^ $key[0]; my $b = (($n[1] & 15) << 4) | ($n[2] >> 2) ^ $key[1]; my $c = (($n[2] & 3) << 6) | $n[3] ^ $key[2]; @key = ($a, $b, $c); @key = map {$x[$_] ^ $key[$_]} (0 ... 2); $str .= pack('C3', $a, $b, $c); } $str =~ s/[\x00]*$//; return $str; } return $string; } # MD5にて暗号化 sub encrypt{ my $c = crypt($_[0], '$1$'.$_[1]); if($c =~ m'^\$1\$'){ *encrypt = sub{ substr(crypt($_[0], '$1$'.$_[1]), -22) }; return substr($c, -22); } eval{ require Digest::MD5; 1; } or die("実行には Digest::MD5 モジュールが必要です\n"); *encrypt = \&unix_md5_crypt; goto &encrypt; } sub unix_md5_crypt{ my ($pw, $salt) = @_; $salt = substr((split /\$/, $salt, 2)[0], 0, 8); my $passwd = &Digest::MD5::md5($pw.$salt.$pw); my $key = $pw.'$1$'.$salt; for(my $pl = length($pw); $pl > 0; $pl -= 16){ $key .= substr($passwd, 0, $pl > 16 ? 16 : $pl); } for(my $i = length($pw); $i; $i >>= 1){ $key .= $i & 1 ? "\x00" : substr($pw, 0, 1); } $passwd = &Digest::MD5::md5($key); for($i = 0; $i < 1000; $i++){ my $key = $i & 1 ? $pw : substr($passwd, 0, 16); $key .= $salt if $i % 3; $key .= $pw if $i % 7; $key .= $i & 1 ? substr($passwd, 0, 16) : $pw; $passwd = &Digest::MD5::md5($key); } my @passwd = map{ord(substr($passwd, $_, 1))} (12, 6, 0, 13, 7, 1, 14, 8, 2, 15, 9, 3, 5 ,10, 4, 11); $passwd = ''; while(my ($a, $b, $c) = splice(@passwd, 0, 3)){ $passwd .= ('.', '/', '0' .. '9', 'A' .. 'Z', 'a' .. 'z')[$_ & 0x3f] foreach ($a, ($a >> 6) | ($b << 2), ($b >> 4) | ($c << 4), $c >> 2); } substr($passwd, 0, 22); }

関連するQ&A