【问题标题】:js-mcrypt and php's mcrypt are not outputting the same valuesjs-mcrypt 和 php 的 mcrypt 没有输出相同的值
【发布时间】:2014-01-29 00:39:34
【问题描述】:

我需要在 JavaScript 中使用 AES 加密数据,然后将其发送到我们的服务器以供 PHP 解密。是的,我知道,这是不安全的,人们将能够解密它 - 我们正在使用它来让人们更难反转和去混淆我们的代码。

我正在使用这个库:

https://github.com/Dexus/js-mcrypt/blob/master/mcrypt.js

我将 Rijndael-128 和 cbc 用于 AES,块大小为 16。我已经验证这个值对于 PHP 和 JS 是相同的。我可以在 JS 和 PHP 中使用相同的密钥 IV 和 rijndael-128/cbc 加密和解密字符串,但由于某种原因 PHP 无法解密 JS 的输出。有人可以帮我指出我做错了什么吗?

代码如下:

<script type="text/javascript" src="Serpent.js"></script>
<script type="text/javascript" src="rijndael.js"></script>
<script type="text/javascript" src="mcrypt.js"></script>

<?php
    function hex2bin($text)
    {
        return pack('H*', $text);
    }

    echo mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    echo "->" . mcrypt_get_key_size('rijndael-128', 'cbc');

    $ciphertext_hex = "86B83EB77A6D40CACABAD79F0EA335E8454B1A9974B2D89D43B3EE0E25B649FB19EB88DF7A4490F9AB05F44701F081DD";
    $ciphertext = hex2bin($ciphertext_hex);

    $key_hex = "31323334353637383930313233343536";
    $key = hex2bin($key_hex);

    $iv = "1234567890123456";
    $cipher = "rijndael-128";
    $mode = "cbc";

    $plaintext = mcrypt_decrypt($cipher, $key, $ciphertext, $mode, $iv);

    echo "<h2>Enc in JS, Dec in PHP</h2>Encrypted: $ciphertext<br /><br />\n\nDecrypted: $plaintext";

    echo "<h2>Enc/Dec in PHP</h2>Encrypted: " . ($encd = mcrypt_encrypt($cipher, $key, "this is the message I want to encode", $mode, $iv)) . "<br><br>\n\n";
    echo "Decrypted: " . mcrypt_decrypt($cipher, $key, $encd, $mode, $iv);
?>

<div id='js_results'></div>
<script>
    var hexdigits='0123456789ABCDEF';
    var hexLookup=Array(256);
    for(var i=0;i<256;i++)
        hexLookup[i]=hexdigits.indexOf(String.fromCharCode(i));

    var bin2hex=function(str){
        var out='';
        for(var i=0;i<str.length;i++)
            out+=hexdigits[str.charCodeAt(i)>>4]+hexdigits[str.charCodeAt(i)&15];
        return out;
    }

    var hex2bin=function(str){
        var out='';
        var part=-1;
        for(var i=0;i<str.length;i++){
            var t=hexLookup[str.charCodeAt(i)]
            if(t>-1){
                if(part>-1){
                    out+=String.fromCharCode(part|t);
                    part=-1;
                }else
                    part=t<<4;
            }
        }
        return out;
    }

    var cipher = "<?php echo $cipher; ?>";
    var mode = "<?php echo $mode; ?>";
    var key = hex2bin("<?php echo $key_hex; ?>");
    var iv = "<?php echo $iv; ?>";
    var msg = "this is the message I want to encode";

    var enc = mcrypt.Encrypt(msg, iv, key, cipher, mode);
    var enc_hex = bin2hex(enc);

    var enc_hex_static = "<?php echo $ciphertext_hex; ?>";
    var enc_static = hex2bin(enc_hex_static);
    var dec = mcrypt.Decrypt(enc_static, iv);

    document.getElementById('js_results').innerHTML = "<h2>Enc in JS</h2>Encrypted: " + enc + "<br><br>\n\nEnc in Hex: " + enc_hex + "<br><br>\n\nDec: " + dec;

</script>

【问题讨论】:

    标签: javascript php encryption aes mcrypt


    【解决方案1】:

    解决方案的一部分是解决您的编码很早就出错的原因。 eg:密文上hex2bin后的字符串,对比js/php。我使用不同的函数来测试输出( hex2bin 的不同实现),但除了你的实际密文在 js/php 之间不同之外,我无法查明特定位置的错误。我会试着找一些时间来弄清楚如何解决这个问题。

    【讨论】:

      【解决方案2】:

      将两个字符串转换为使用相同的字符编码,如 utf8

      【讨论】:

      • 你的意思是加密的字符串?
      • 纯文本字符串
      • 将要编码的javascript字符串转换为utf8,并将PHP中的解码输出转换为utf8,不幸的是没有解决问题
      猜你喜欢
      • 2014-08-14
      • 2015-06-17
      • 2013-06-06
      • 1970-01-01
      • 2013-04-01
      • 2015-07-27
      • 2014-05-14
      • 1970-01-01
      • 2017-11-12
      相关资源
      最近更新 更多