[英]CryptoJS Aes decryption in php not working
我再次问这个问题,因为我没有正确回答我的最后一个问题,我正在制作CMS,并且我已经制作了一个加密系统(使用cryptoJs),以为不使用ssl或ssl的网站所有者提供更高的安全性tls。 但是当我解密php中的代码时,我得到了:
éû*ö^ÿçÿ/Œæ”‰0äU
我试图查看它是否为十六进制,但是当我尝试将其从十六进制转换为UTF-8时,它也给了我一点杂乱的感觉。
我的系统以这种方式工作:每次用户进入页面时,都会创建两个随机字符串,每个字符串长100个字符。 这些字符串是adk
(Aes解密密钥)和keyT
。 adk是密钥的秘密密码,而keyT将是用于存储密钥的cookie的名称。 随机字符串创建脚本(PHP):
$characters = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789";
$charactersLength = strlen($characters);
$adk = "";
for($i=0;$i<100;$i++)
{
$adk .= $characters[rand(0, $charactersLength - 1)];
}
$_SESSION['adk'] = $adk;
$characters2 = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789";
$charactersLength2 = strlen($characters);
$keyT = "";
for($i=0;$i<100;$i++)
{
$keyT .= $characters2[rand(0, $charactersLength2 - 1)];
}
$_SESSION['keyT'] = $keyT;
我还使用CryptoJS扩展来创建密码安全的随机数,而不是使用 Math.random()
CryptoJS扩展(Javascript):
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 artjomb
*/
(function(C){
var WordArray = C.lib.WordArray;
var crypto = window.crypto;
var TypedArray = Int32Array;
if (TypedArray && crypto && crypto.getRandomValues) {
WordArray.random = function(nBytes){
var array = new TypedArray(Math.ceil(nBytes / 4));
crypto.getRandomValues(array);
return new WordArray.init(
[].map.call(array, function(word){
return word
}),
nBytes
);
};
} else {
console.log("No cryptographically secure randomness source available");
}
})(CryptoJS);
密码加密脚本(Javascript&PHP):
function savePassword()
{
password = document.getElementById("ap").value;
var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);
var key = CryptoJS.PBKDF2(<?php echo '"'.$_SESSION['adk'].'"'; ?>, salt, { keySize: 256/32, iterations: 900 });
password = CryptoJS.AES.encrypt(password, key, { iv: iv });
var pB64 = password.ciphertext.toString(CryptoJS.enc.Base64);
var ivB64 = password.iv.toString(CryptoJS.enc.Base64);
var kB64 = password.key.toString(CryptoJS.enc.Base64);
document.cookie=<?php echo '"'.$_SESSION['keyT'].'="'; ?> + kB64 + "; path=/";
document.cookie="encrIv=" + ivB64 + "; path=/";
$(document).ready(function()
{
$("#ap").slideToggle("slow");
$("#sp").slideToggle("slow");
$("#tempBr").remove();
$("#apText").slideToggle("slow");
$("#nb").slideToggle("slow");
$("#sp").remove();
$("#ap").text(pB64);
});
}
iv和key放在cookie中,但是密码将以表单的形式发布到下一页,并将其存储在会话中。
表单文本框(HTML):
<input type="password" id="ap" name="ap" class="textbox" placeholder="Administrator password" />
加密密码存储脚本(PHP):
$ap = $_POST['ap'];
include_once("../scripts/session_start.php");
$_SESSION['ap'] = $ap;
解密脚本(PHP):
<?php
include_once("scripts/session_start.php");
$keyT = $_SESSION['keyT'];
$toDecrypt = $_SESSION['ap'];
$iv = $_COOKIE['encrIv'];
$key = $_COOKIE[$keyT];
$toDecrypt = base64_decode($toDecrypt);
$iv = base64_decode($iv);
$key = base64_decode($key);
$decrypted = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $toDecrypt, MCRYPT_MODE_CBC, $iv ), "\t\0" );
echo $decrypted;
?>
对于这个匆忙的答案,我感到抱歉-我明天晚些时候会清理它-但总的来说 , 要让CryptoJS和PHP一起工作并不容易 。
首先,您必须获得正确的AES模式(GoogleCode CryptoJS和PHP mcrypt之间的模式不同),然后是具有填充和IV的怪癖。
下面的代码已经运行了十八个月了。 PHP和JS代码混杂在一起。
public static function aesEncrypt($password, $plaintext, $js = true) {
$key = self::getAesKey($password, !$js);
// Build $iv and $iv_base64.
// We use a block size of 128 bits (AES compliant) and CBC mode.
// (Note: ECB mode is inadequate as IV is not used.)
if (!function_exists('mcrypt_create_iv')) {
die('FATAL: php5-mcrypt package does not seem to be installed');
}
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
return base64_encode(
$iv // S a l t e d _ _
. (true === $js ? hex2bin('53616c7465645f5f0000000000000000') : '')
. mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
// Add a payload of 32 spaces.
str_repeat(' ', true === $js ? 32 : 0) . $plaintext,
MCRYPT_MODE_CBC,
$iv
)
);
$encrypt = Crypto::aesEncrypt(
PASSWORD
MESSAGE
);
<script src="/static/js/aes.js"></script>
<script src="/static/js/sha256.js"></script>
<script>
// Decode the base64 data so we can separate iv and crypt text.
var rawData = atob('{$encrypt}'); // Base64, IV plus naked ciphertext
var iv = CryptoJS.enc.Latin1.parse(rawData.substring(0, 16));
var encrypt = CryptoJS.enc.Latin1.parse(rawData.substring(16));
document.getElementById('password').onkeydown = function(e) {
if (13 === e.keyCode) {
decrypt();
}
};
function hex2a(hex) {
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
function decrypt() {
var passw = document.getElementById('password').value;
var key = CryptoJS.SHA256(passw);
var plain = CryptoJS.AES.decrypt({ ciphertext: encrypt }, key, { iv: iv });
// Skip first 16 + 32 bytes of decrypted text.
document.getElementById('details').innerHTML = hex2a(plain.toString().substr(96));
}
我找到了一种解决方法,加密的密码将存储在cookie中,稍后再由cryptoJS解密。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.