#php #jquery #encryption #cryptojs
#php #jquery #шифрование #cryptojs
Вопрос:
В моем коде я шифрую некоторые данные два раза. Сначала в jQuery:
var text = '' CryptoJS.Rabbit.encrypt("12345", "PassPhrase");
затем это отправляется с помощью ajax в php и снова шифруется:
function mc_encrypt($encrypt, $key){
$encrypt = serialize($encrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
$key = pack('H*', $key);
$mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
$passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
$encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
return $encoded;
}
После этого это сохраняется в базе данных. Если пользователь хочет снова получить доступ к значению, я извлекаю его из базы данных и затем расшифровываю:
function mc_decrypt($decrypt, $key){
$decrypt = explode('|', $decrypt);
$decoded = base64_decode($decrypt[0]);
$iv = base64_decode($decrypt[1]);
$key = pack('H*', $key);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
$mac = substr($decrypted, -64);
$decrypted = substr($decrypted, 0, -64);
$calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
if($calcmac!==$mac){ return false; }
$decrypted = unserialize($decrypted);
return $decrypted;
}
Затем это отправляется обратно в jQuery и снова расшифровывается:
var text = CryptoJS.Rabbit.decrypt(text, "PassPhrase");
text = text.toString();
console.log(text);
Однако значение, зарегистрированное в консоли, сильно отличается от значения (‘12345’) в начале. Я не знаю, почему это происходит, и я изучал эту проблему последние два дня, но, похоже, не могу понять проблему…
Комментарии:
1. Во-первых, почему вы это делаете? Почему «двойное» шифрование лучше?
2. если вы получаете разные значения, значит, вы неправильно зашифровали и / или расшифровали. Функции не заботятся о том, все ли «правильно». они просто берут некоторые данные и выполняют с ними кучу математических операций. Если математика идет не так, функциям все равно, они просто будут делать то, что им говорят.
3. Вы пробовали сравнивать ввод / вывод только части PHP? Помогло бы определить, в чем проблема
4. Дело не в том, что двойное шифрование лучше, а в том, что я не хочу отправлять данные в незашифрованном виде в файл PHP.
5. @user3740505 Если вы беспокоитесь о том, что данные не зашифрованы во время транспортировки, для этого и нужен SSL
Ответ №1:
CryptoJS.Rabbit.decrypt возвращает массив слов, и вы вызываете для него toString . Для «12345» я бы предположил, что результат, который вы видите, — «3132333435».
Используйте CryptoJS stringify, например, CryptoJS.enc.Utf16.stringify(текст) или CryptoJS.enc.Utf8.stringify(текст), в зависимости от исходной кодировки.
Вы можете выбрать кодировку по пути, изменив свой код, например, так:
p = CryptoJS.enc.Utf8.parse("12345");
text = '' CryptoJS.Rabbit.encrypt(p, "PassPhrase");
Затем на обратном пути:
var text = CryptoJS.Rabbit.decrypt(text, "PassPhrase");
text = CryptoJS.enc.Utf8.stringify(text); // use same encoding as original input
console.log(text);