首页 文章

php mcrypt to javascript aes integration

提问于
浏览
8

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

我知道javascript的问题本质以及任何人都看到密钥的事实,但我使用javascript作为非Web环境的脚本工具 - 所以不要担心它 .

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

并使用演示页面加密了一些数据,然后尝试通过php解密它,但是出了点问题,我似乎无法找到什么......我使用相同的键,两端都是32字节的字符串

任何指针将不胜感激


```java
$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;
```

5 回答

  • 0

    尝试使用带有32字节密钥的MCRYPT_RIJNDAEL_128进行AES-256 .

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

  • 0

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

  • 1

    Javascript Mcrypt与PHP mcrypt配合得很好 . 您可以使用它而不是pidder .

  • 0

    你的代码是顺序的,老实说,我没有尝试修复,但我有一个功能很好,可以帮助你 .

    /**
     * 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

  • 0

    首先: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函数包含填充,这是一个重要的部分,因为如果提供的数据长度不是密钥的倍数,你会得到奇怪的东西 .

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

    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使用它的加密库 .

    我希望这适合你 .

相关问题