use*_*769 29 javascript php encryption cryptojs
我在基本加密/解密方面遇到了麻烦.我一直在寻找一个有效的例子,但还没有找到一个有效的例子.
- 我将在php中进行加密,使用cryptoj解密以获得一小部分安全性
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js">
<?
$text = "this is the text here";
$key = "encryptionkey";
$msgEncrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND));
$msgBase64 = trim(base64_encode($msgEncrypted));
echo "<h2>PHP</h2>";
echo "<p>Encrypted:</p>";
echo $msgEncrypted;
echo "<p>Base64:</p>";
echo $msgBase64;
?>
<p>AES Decrypt</p>
<script>
var key = 'encryptionkey';
var encrypted = "<?php echo $msgBase64 ?>";
//tried var base64decode = CryptoJS.enc.Base64.parse(encrypted);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
console.log( decrypted.toString(CryptoJS.enc.Utf8) );
</script>
Run Code Online (Sandbox Code Playgroud)
我错过了哪一步?
Bra*_*ong 56
我需要同样的东西,我写了一个简短的库,适用于CryptoJS 3.x和PHP,支持openssl.希望这有帮助,源代码和示例文件在这里https://github.com/brainfoolong/cryptojs-aes-php
/**
* Decrypt data from a CryptoJS json encoding string
*
* @param mixed $passphrase
* @param mixed $jsonString
* @return mixed
*/
function cryptoJsAesDecrypt($passphrase, $jsonString){
$jsondata = json_decode($jsonString, true);
$salt = hex2bin($jsondata["s"]);
$ct = base64_decode($jsondata["ct"]);
$iv = hex2bin($jsondata["iv"]);
$concatedPassphrase = $passphrase.$salt;
$md5 = array();
$md5[0] = md5($concatedPassphrase, true);
$result = $md5[0];
for ($i = 1; $i < 3; $i++) {
$md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true);
$result .= $md5[$i];
}
$key = substr($result, 0, 32);
$data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
return json_decode($data, true);
}
/**
* Encrypt value to a cryptojs compatiable json encoding string
*
* @param mixed $passphrase
* @param mixed $value
* @return string
*/
function cryptoJsAesEncrypt($passphrase, $value){
$salt = openssl_random_pseudo_bytes(8);
$salted = '';
$dx = '';
while (strlen($salted) < 48) {
$dx = md5($dx.$passphrase.$salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32,16);
$encrypted_data = openssl_encrypt(json_encode($value), 'aes-256-cbc', $key, true, $iv);
$data = array("ct" => base64_encode($encrypted_data), "iv" => bin2hex($iv), "s" => bin2hex($salt));
return json_encode($data);
}
Run Code Online (Sandbox Code Playgroud)
var CryptoJSAesJson = {
stringify: function (cipherParams) {
var j = {ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)};
if (cipherParams.iv) j.iv = cipherParams.iv.toString();
if (cipherParams.salt) j.s = cipherParams.salt.toString();
return JSON.stringify(j);
},
parse: function (jsonStr) {
var j = JSON.parse(jsonStr);
var cipherParams = CryptoJS.lib.CipherParams.create({ciphertext: CryptoJS.enc.Base64.parse(j.ct)});
if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv)
if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s)
return cipherParams;
}
}
Run Code Online (Sandbox Code Playgroud)
var encrypted = CryptoJS.AES.encrypt(JSON.stringify("value to encrypt"), "my passphrase", {format: CryptoJSAesJson}).toString();
var decrypted = JSON.parse(CryptoJS.AES.decrypt(encrypted, "my passphrase", {format: CryptoJSAesJson}).toString(CryptoJS.enc.Utf8));
Run Code Online (Sandbox Code Playgroud)
$encrypted = cryptoJsAesEncrypt("my passphrase", "value to encrypt");
$decrypted = cryptoJsAesDecrypt("my passphrase", $encrypted);
Run Code Online (Sandbox Code Playgroud)
Jim*_*ood 14
Scott Arciszewski 安全声明:此答案的代码容易受到选择密文攻击.请参阅此答案以获取安全加密.
这是一个用PHP加密字符串并使用CryptoJS解密它的工作示例.
在PHP方面:
使用MCRYPT_RIJNDAEL_128(不是256)与AES配对.这里的128是块大小,而不是密钥大小.
也发送IV.您需要IV才能解密.
$text = "this is the text here";
$key = "encryptionkey";
// Note: MCRYPT_RIJNDAEL_128 is compatible with AES (all key sizes)
$iv = random_bytes(16);
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
echo "iv:".base64_encode($iv)."\n";
echo "ciphertext:".base64_encode($ciphertext)."\n";
Run Code Online (Sandbox Code Playgroud)
以下是测试运行的示例输出:
iv:BMcOODpuQurUYGICmOqqbQ==
ciphertext:ZJAab8YtkRq5TL7uyIR7frM2b3krftJzn1pTqRTAda4=
Run Code Online (Sandbox Code Playgroud)
Scott Arciszewski 重要提示:因为我们没有对我们的密文进行身份验证,所以解密变得容易受到填充oracle攻击.另请参见:PHP中的身份验证加密.
在CryptoJS方面:
你的密钥只有13个ASCII可打印字符,非常弱.Mcrypt 使用ZERO字节将密钥填充到有效的密钥大小.
将密钥和IV转换为字阵列.
我没有太多运气用密文作为字数组解密,所以我把它保留为Base64格式.
CryptoJS = require("crypto-js")
// Mcrypt pads a short key with zero bytes
key = CryptoJS.enc.Utf8.parse('encryptionkey\u0000\u0000\u0000')
iv = CryptoJS.enc.Base64.parse('BMcOODpuQurUYGICmOqqbQ==')
// Keep the ciphertext in Base64 form
ciphertext = 'ZJAab8YtkRq5TL7uyIR7frM2b3krftJzn1pTqRTAda4='
/**
* DANGER DANGER WILL ROBINSON! <== Stop editing my answer or I will delete it.
*
* This example code doesn't demonstrate AUTHENTICATED ENCRYPTION
* and is therefore vulnerable to chosen-ciphertext attacks.
*
* NEVER USE THIS CODE TO PROTECT SENSITIVE DATA!
*/
// Mcrypt uses ZERO padding
plaintext = CryptoJS.AES.decrypt(ciphertext, key, { iv: iv, padding: CryptoJS.pad.ZeroPadding })
// I ran this in nodejs
process.stdout.write(CryptoJS.enc.Utf8.stringify(plaintext))
Run Code Online (Sandbox Code Playgroud)
小智 6
不要太深入编码,只需使用 Base64 解码器
在php代码上:
$encrypt_val=base64_encode("value");
Run Code Online (Sandbox Code Playgroud)
在 js 上:
var my_orignal_val = window.atob(passed_val);
Run Code Online (Sandbox Code Playgroud)
这足以满足您的要求。
您正在使用两个库,它们试图容纳严格来说无效的输入。Rijndael 需要 16、24 或 32 字节长的随机字节字符串的密钥。您提供 13 个字符的字符串。PHP 库 Mcrypt 直接使用字符串(可能是 utf8 编码)作为二进制输入,并将其用零填充到MCRYPT_RIJNDAEL_256. 另一方面,CryptoJS确定您输入了类似密码的内容,而是使用密钥派生函数来生成 32 字节密钥。
此外,所使用的加密算法甚至不匹配。Mcrypt 在 256 位版本中使用了原始 Rijndael 的很少实现的变体,而 CryptoJS 则实现了 Rijndael 提案广为人知的 AES256 变体。MCRYPT_RIJNDAEL_128不过,两者(和 AES128)的 128 位版本是相同的。
稍后您将面临的第三个问题是,Mcrypt 还对加密数据使用了疯狂的填充方案。由于 Rijndael 是一种分组密码,因此它只能加密 16、24 或 32 字节的块(具体取决于变体 - AES 始终使用 16 字节块)。因此必须填充此类数据。Mcrypt 通过仅附加零以非内射方式完成此操作。如果您只编码字符串,这对您来说不会是太大的问题,因为 utf8 编码的字符串永远不会包含零字节,因此您可以将它们剥离(CryptoJS 甚至本机支持)。
解决所有这些问题的最简单方法是避免自己实现任何密码学(无论如何,如果没有对该主题的广泛了解,强烈建议不要这样做)。您能否改为通过 https 传输您的敏感信息,而 https 将使用 TLS(以前称为 SSL)来加密和验证通道?
| 归档时间: |
|
| 查看次数: |
39550 次 |
| 最近记录: |