dornc9470 2016-06-05 12:29
浏览 148
已采纳

使用CryptoJS进行AES加密并使用CodeIgniter进行解密

I'm trying to encrypt a username sent via POST request to my server (written in Codeigniter 3), so I'm encrypting on the client side with CryptoJS like so:

var user = $('.user').val();
var key = "<? echo($key);?>"; //$key is created on the server side
var encUser = CryptoJS.AES.encrypt(user, key, {
    mode: CryptoJS.mode.CBC
}).toString();

I get a fine looking 64 characters long string, which I send to my server.

On my server (running CodeIgniter 3) I am using the CI encryption library and I'm loading it as required, but when I try to decrypt the string like so:

$this->encryption->decrypt($this->input->post('encUser'), array(
    'cipher' => 'aes-128',
    'mode' => 'cbc',
    'hmac' => FALSE,
    'key' => $key
));

the function returns (bool)false, meaning something went wrong.

What am I doing wrong?

Note: not sure how much I need to encrypt with iv because the CI library just uses the first 16 chars from the string itself.

** EDIT **

I'm creating my $kay (passphrase) with the help of the random_int polyfill and this is my function:

private function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $str = '';
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $str .= $keyspace[random_int(0, $max)];
    }
    return $str;
}

Which i am calling random_str(32);

Example generated key: 1xB8oBQgXGPhcKoD0QkP1Uj4CRZ7Sy1c

** UPDATE ** thanks to Artjom.B's answer(and chat :) ) we got it working, using his answer's client side code and fixing the server side code to be:

$user = $this->encryption->decrypt(base64_decode($this->input->post('encUser')), array(
        'cipher' => 'aes-256',
        'mode' => 'cbc',
        'hmac' => FALSE,
        'key' => $key
    ));

and now everything is working.

  • 写回答

1条回答 默认 最新

  • drgawfsf1069 2016-06-05 12:52
    关注

    In CryptoJS, if key is a string, then it will assume that key is actually a password, generate a random salt and derive the actual key and IV from password+salt (this is done in an OpenSSL-compatible way through EVP_BytesToKey).

    CodeIgniter's Encryption library doesn't support this type of key derivation. You will either have to change your CryptoJS code to pass in a parsed WordArray:

    var key = CryptoJS.enc.Hex.parse("<? echo(bin2hex($key));?>");
    var iv = CryptoJS.lib.WordArray.random(128/8);
    var encUser = CryptoJS.AES.encrypt(user, key, {
        iv: iv
    }).ciphertext;
    return iv.concat(encUser).toString(CryptoJS.enc.Base64);
    

    Since the IV is written in front of the ciphertext, CodeIgniter should read it correctly and it doesn't have to be specified explicitly. Make sure that key is correctly encoded as Hex or Base64, because binary encoding doesn't work in JavaScript correctly. Also, at the PHP side, the ciphertext must be decoded from Base64.

    You could also implement EVP_BytesToKey in PHP as I've shown here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?