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

菊澤 正明 kikuzawa @ cyber-coo.com
2007年 3月 10日 (土) 11:50:22 JST


菊澤と申します。

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 @ cyber-coo.com



PHP-users メーリングリストの案内