[PHP-users 31653] PHP mcryptとjavascript間での暗号化/復号化につい

View: New views
3 Messages — Rating Filter:   Alert me  

[PHP-users 31653] PHP mcryptとjavascript間での暗号化/復号化につい

by Higuchi Atsushi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

mcrypt関数で暗号化したデータをjavascriptで復号化(またはその逆)したいのですが、うまくできず困っています。
テストで使用しているPHPのコードは以下のようなものです。

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_BLOWFISH,
MCRYPT_MODE_CBC), MCRYPT_RAND);
$text = "123 456 789 0123"; // 暗号化するテキスト
$key = "key";
$encrypted = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);

$encoded = base64_encode($encrypted);
print $encoded."\n"; // 符号化済みのテキスト

// ここから復号化処理
$decoded = base64_decode($encoded);
$decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $decoded,
MCRYPT_MODE_CBC, $iv);
print str_replace("\0", "", $decrypted);

このプログラム内では暗号化/復号化は正常に動作しているので、PHP同士では問題ないようです。

javascriptは以下のページのサンプルを使わせてもらいました。
http://user1.matsumoto.ne.jp/~goma/js/blowfish.html

このページ内で、PHPによって暗号化、符号化されたデータ(上記の例の中の$encoded)を復号化すると、平文の最初の2つのスペースまでの部分が途切れてしまい、表示される結果は"789
0123"になってしまいます。スペースが含まれていない場合は結果は空になります。

逆に、javascriptで暗号化したものをPHPで復号化すると、今度は復号化されたテキストの先頭に"˜j_ á¯w123 456 789
0123"のような感じでゴミが付いてしまいます。
何か途中に他の処理が必要なのでしょうか?

--
Atsushi Higuchi
_______________________________________________
PHP-users mailing list  PHP-users@...
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください
http://www.php.gr.jp/php/novice.php3

[PHP-users 31663] Re: PHP mcryptとjavascript間での暗号化/復号化につい

by 菊澤 正明 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


菊澤と申します。

javascript側の復号化のソースを見たところ、復号化すべき
データの先頭にivがあることを期待しています。

iv+暗号化されたデータ
という構成のデータでないと複合化できません。

blowfishの場合、8バイトをivとして扱いますので、暗号化された
データだけ渡してしまうと、暗号化されたデータの先頭8バイトをiv
としてしまい復号時、先頭8バイト分がなくなってしまいます。

ですので、
$js_encoded = base64_encode($iv.$encrypted);
として、$js_encodedをjavascript側に渡してやれば良いかと思います。

また、javascript側から渡される暗号を復号するには、
$decoded = base64_encode($js_base64);
$iv = substr($decoded, 0, 8);
$encrypted = substr($decoded, 8);
$decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
とすれば良いかと思われます。

あんま、暗号のことは判らんのですが、ソースがそうなってましたので。


テストしたサンプル

○PHPで暗号化してJAVASCRIPTで復号する
<?php
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_CBC), MCRYPT_RAND);
$text = "123 456 789 0123";
$key = "12345678";
$encrypted = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $text, MCRYPT_MODE_CBC, $iv);
$js_encoded = base64_encode($iv.$encrypted);

?>
<html>
<head>
<script language='javaScript' src='mcrypt.js'></script>
<script language='javaScript' src='base64.js'></script>
</head>
<body>
<script language='javaScript'>
    encrypted = base64.decode("<?=$js_encoded?>");
    var usr = {
        data    : encrypted,
        key     : "12345678",
        mode    : "cbc",
        round   : 16,
        pchar   : "\0"
    };
    decrypted = blowfish.decrypt(usr);
    document.write("復号したテキスト = " + decrypted + "<BR>\r\n");
</script>
</body>

○JAVASCRIPTで暗号化してPHPで復号する
<?php
if (array_key_exists('text_data', $_REQUEST) && strlen($_REQUEST['text_data']) > 0) {
    $key = "12345678";
    $decoded = base64_decode($_REQUEST['text_data']);
    $iv = substr($decoded, 0, 8);
    $encrypted = substr($decoded, 8);
    $decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
}
?>
<html>
<head>
<script language='javaScript' src='mcrypt.js'></script>
</head>
<body>
<?php
if (array_key_exists('text_data', $_REQUEST) && strlen($_REQUEST['text_data']) > 0) {
    echo "テキストデータ({$decrypted})を受信しました";
}
?>
<script language='javaScript'>
function encrypt()
{
    var usr = {
        data    : document.f.text_data.value,
        key     : "12345678",
        mode    : "cbc", //"cbc",
        round   : 16,
        iv      : blowfish.mkIV(),
        pchar   : "\0"
    };
    encrypted = blowfish.encrypt(usr);
    document.f.text_data.value = base64.encode(encrypted);
    return true;
}
</script>
<form name=f method='post' onSubmit='return encrypt()'>
<input type='text' name='text_data' size='32'>
<input type='submit' value='暗号化して送信'>
</form>
</body>

--------------------------------------------
菊澤 正明  mailto:kikuzawa@...

_______________________________________________
PHP-users mailing list  PHP-users@...
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください
http://www.php.gr.jp/php/novice.php3

[PHP-users 31674] Re: PHP mcryptとjavascript間での暗号化/復号化につい

by Higuchi Atsushi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

なるほど、ivを先頭に付け足さないといけなかったんですね。javascriptのほうのコードを見ずにずっとサンプルのページを使って復号化できないと悩んでいました。
サンプルまでわざわざ付けてくださってありがとうございました。とても助かりました。

--
Atsushi Higuchi
_______________________________________________
PHP-users mailing list  PHP-users@...
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください
http://www.php.gr.jp/php/novice.php3