【问题标题】:php mcrypt to javascript aes integrationphp mcrypt 到 javascript aes 集成
【发布时间】:2011-09-18 06:56:45
【问题描述】:

我正在尝试使用 javascript 对数据进行编码,使用 AES-256-CBC 和 php mcrypt 库进行解码,反之亦然。

我知道 javascript 的问题性质以及任何人都可以看到密钥这一事实,但我正在使用 javascript 作为非 Web 环境的脚本工具 - 所以不用担心。

我找到了 pidder https://sourceforge.net/projects/pidcrypt/

并使用演示页面加密了一些数据,然后尝试通过 php 对其进行解密,但出现了问题,我似乎找不到什么...我使用的是两端相同的密钥,一个 32 字节的字符串

任何指针将不胜感激

~~~

$encrypted = "string after pidder encryption";  

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_256,'',MCRYPT_MODE_CBC,'');    

$iv_size = mcrypt_enc_get_iv_size($cipher);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

mcrypt_generic_init($cipher, $key, $iv);


$encrypted = base64_decode($encrypted);

echo "after b64decode: " . $encrypted . "\n\n\n";

$encrypted = mdecrypt_generic($cipher, $encrypted);

echo "decrypt:" . $encrypted;

~~~

【问题讨论】:

  • 嗯,在我看来MCRYPT_RIJNDAEL_256 不是AES-256。可能不是您代码中的唯一问题,但可能是一个开始。
  • Rijndael 是 AES,只是算法名称不同。

标签: javascript php encryption aes pidcrypt


【解决方案1】:

尝试 MCRYPT_RIJNDAEL_128 和 AES-256 的 32 字节密钥。

AES 是一种 128 位分组密码,支持 128、192 和 256 位密钥。 Rijndael-256 是 256 位分组密码和 AES。 AES 是 Rijndael 的 128 位块规范。

【讨论】:

    【解决方案2】:

    Pidder 使用密钥派生函数从密码中获取密钥(我猜应该是 HMAC-SHA1),但您似乎使用普通密码作为密钥。

    【讨论】:

    • 我已经有一个 32 字节长的十六进制密钥,我想用它同时提供 pidder 和 mcrypt,但它似乎 pidder 首先操纵它.. 知道如何让他们“说话” ?
    • 我还可以使用不同的 javascript 库在 php 上与 mcrypt “对话”,任何工作代码示例?
    【解决方案3】:

    Javascript Mcrypt 与 PHP mcrypt 配合得很好。您可以使用它来代替 pidder。

    【讨论】:

      【解决方案4】:

      你的代码是连续的,老实说,我没有尝试修复,但我有一个运行良好的函数,可以帮助你。

          /**
       * Encrypt Token
       *
       * @param unknown $text         
       */
      private function rijndaelEncrypt($text) {
          $iv_size = mcrypt_get_iv_size ( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB );
          $iv = mcrypt_create_iv ( $iv_size, MCRYPT_RAND );
          $key = 'your key';
          return base64_encode ( mcrypt_encrypt ( MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv ) );
      }
      
      /**
       * Decrypt
       *
       * @param unknown $text         
       */
      private function rijndaelDecrypt($text) {
          $iv_size = mcrypt_get_iv_size ( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB );
          $iv = mcrypt_create_iv ( $iv_size, MCRYPT_RAND );
          $key = 'your key';
          // I used trim to remove trailing spaces
          return trim ( mcrypt_decrypt ( MCRYPT_RIJNDAEL_256, $key, base64_decode ( $text ), MCRYPT_MODE_ECB, $iv ) );
      }
      

      http://us3.php.net/manual/en/function.mcrypt-encrypt.php

      【讨论】:

        【解决方案5】:

        首先:MCRYPT_RIJNDAEL_256 不是(!)AES-256-CBC,如果您想要这种加密,您必须使用 MCRYPT_RIJNDAEL_128 和 265 位,也就是 32 个字符的密钥。

        这将是 php 部分:

        function decrypt($data, $key) {
            if(32 !== strlen($key)) $key= hash('SHA256', $key, true);
        
            $data = base64_decode($data);
            $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
            $padding = ord($data[strlen($data) - 1]); 
        
            return substr($data, 0, -$padding); 
        }
        

        这个 php 函数包括填充,这是一个重要的部分,因为如果提供的数据长度不是 key 的倍数,你会得到一些奇怪的东西。

        为了解码,我们使用我的一些 Node.js 脚本和 php 的 str_repeat 的模拟方法用于 iv:

        var crypto = require('crypto'); 
        
        function encrypt(data, key) {
            key = key || new Buffer(Core.config.crypto.cryptokey, 'binary'),
                cipher = crypto.createCipheriv('aes-256-cbc', key.toString('binary'), str_repeat('\0', 16));
            cipher.update(data.toString(), 'utf8', 'base64');
            return cipher.final('base64');
        }
        
        function str_repeat(input, multiplier) {
            var y = '';
            while (true) {
                if (multiplier & 1) {
                    y += input;
                }
                multiplier >>= 1;
                if (multiplier) {
                    input += input;
                } else {
                    break;
                }
            }
            return y;
        }
        

        注意:不建议使用静态 IV (Initialization vector)! 注意:JavaScript 部分适用于使用其加密库的 Node.js。

        我希望这对你有用。

        【讨论】:

          猜你喜欢
          • 2011-02-23
          • 2011-10-15
          • 2011-04-04
          • 2014-12-24
          • 2016-02-21
          • 2014-09-12
          • 2011-09-18
          • 2014-06-28
          • 2013-10-21
          相关资源
          最近更新 更多