加密CryptoJS并用PHP解密 [英] Encrypt with CryptoJS and decrypt with PHP

查看:1523
本文介绍了加密CryptoJS并用PHP解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在客户端(移动设备)我使用CryptoJS加密用户密码:

  var lib_crypt = require('aes ); 

$ .loginButton.addEventListener('click',function(e){

var key = lib_crypt.CryptoJS.enc.Hex.parse('bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3');
var iv = lib_crypt.CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');

var encrypted = lib_crypt.CryptoJS.AES.encrypt($。passwordInput.value,key,{iv :iv});

var password_base64 = encrypted.ciphertext.toString(lib_crypt.CryptoJS.enc.Base64);
return password_base64;
});

在服务器端我想使用mcrypt_decrypt解密:

  function decryptPassword($ password)
{
$ key = pack('H *',bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3);
$ ciphertext_dec = base64_decode($ password);
$ iv_dec =101112131415161718191a1b1c1d1e1f;

$ ciphertext_dec = substr($ ciphertext_dec,16);
$ decryptptedPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$ key,$ ciphertext_dec,MCRYPT_MODE_CBC,$ iv_dec);

return trim($ decryptptedPassword);
}

我使用相同的键和IV,我做错了什么? p>

解决方案

双方都没有做同样的事情。



IV



您在CryptoJS中解析了IV,但忘了在PHP中执行:

  $ iv_dec = pack('H *',101112131415161718191a1b1c1d1e1f); 

要修复您的IV错误,您可能注意到前16个字节是乱码。当IV错误发生时。请注意,CryptoJS默认使用CBC模式,因此IV在解密过程中仅影响第一个块。 删除

  $ ciphertext_dec = substr($ ciphertext_dec,16); 



填充



您可能注意到,明文不出来。最后他们以一些奇怪的重复字符结束。这是在CryptoJS中默认应用的PKCS#7填充。你必须在PHP中删除填充。好的是,Maarten Bodewes为此此处提供了适当的复制粘贴解决方案。



trim()可能适用于ZeroPadding,但不适用于使用PKCS#7中定义的填充方案。您可以删除 trim()调用,因为它不是有用的,可能会导致意外的明文,因为零字节,空格从开始和结束修剪。 p>

On the client side (mobile device) I encrypt a users password with CryptoJS:

var lib_crypt = require('aes');

$.loginButton.addEventListener('click', function(e){

var key = lib_crypt.CryptoJS.enc.Hex.parse('bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3');
var iv  = lib_crypt.CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');

var encrypted = lib_crypt.CryptoJS.AES.encrypt($.passwordInput.value, key, { iv: iv });

var password_base64 = encrypted.ciphertext.toString(lib_crypt.CryptoJS.enc.Base64); 
return password_base64; 
});

On the server side i want to decrypt it with mcrypt_decrypt:

function decryptPassword($password)
{
    $key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
    $ciphertext_dec = base64_decode($password);
    $iv_dec = "101112131415161718191a1b1c1d1e1f";

    $ciphertext_dec = substr($ciphertext_dec, 16);
    $decryptedPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);

    return trim($decryptedPassword);
}

I use the same key and IV, what do I do wrong?

解决方案

You're not doing the same thing on both sides.

IV

You did parse the IV in CryptoJS, but forgot to do it in PHP:

$iv_dec = pack('H*', "101112131415161718191a1b1c1d1e1f");

To fix that your IV is wrong, you probably noticed that the first 16 bytes are gibberish. That happens when the IV is wrong. Note that CryptoJS uses CBC mode by default, so the IV has only influence on the first block during decryption. Remove this:

$ciphertext_dec = substr($ciphertext_dec, 16);

Padding

You probably noticed that most plaintexts don't come out right. They end with some strange repeated characters at the end. This is the PKCS#7 padding that is applied by default in CryptoJS. You have to remove the padding yourself in PHP. Good thing is that Maarten Bodewes has provided a proper copy paste solution for this here.

trim() might be appropriate for ZeroPadding, but not when a proper padding scheme like the one defined in PKCS#7 is used. You may remove the trim() call altogether, because it is not useful and may result in unexpected plaintext, becauses zero bytes and whitespace is trimmed from the beginning and end.

这篇关于加密CryptoJS并用PHP解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆