当前位置: 首页 > 知识库问答 >
问题:

CryptoJS Aes解密在PHP不工作

叶阳
2023-03-14

我再次问这个问题,因为我的最后一个问题没有得到正确的回答,我正在制作一个CMS,我已经制作了一个加密系统(使用cryptoJs),为不使用ssl或tls的网站所有者提供多一点安全性。但当我用php解密代码时,我得到了以下信息:

ÿÿÿÿ/Œæ

我试着看看它是不是十六进制,但当我试着把它从十六进制转换到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

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和密钥被放入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;
?>

共有2个答案

薛承基
2023-03-14

我找到了一个解决办法,加密的密码将被存储到cookie中,稍后由cryptoJS解密。

刘浩思
2023-03-14

对于这个仓促的回答,我很抱歉——明天晚些时候我会把它清理干净——但长话短说,让CryptoJS和PHP一起工作并不容易。

首先,你必须获得正确的AES模式(Google Code CryptoJS和PHP mcrypt之间的模式不同),然后还有填充和IV的怪癖。

下面的代码已经运行了大约18个月。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));
    }
 类似资料:
  • 接下来,我使用java用接收到的公钥加密字符串,因此我将pkcs8公钥解析为java PublicKey对象。 并用它加密文本 它运行良好,并返回一个Base64编码的加密字符串,如下所示 未捕获的错误:解密时出错(可能是密钥不正确)。原始错误:错误:错误解码消息,从提供的标签计算出的lHash和加密数据中的lHash不匹配。(…)然而,我已经测试过,如果我只在javascript中加密和解密文本

  • 我使用Botan库进行加密,我的加密代码如下所示。 这段代码看起来很好,可以加密输入文件。我发布这段代码是为了确定加密是否有错误。(但我假设加密做得正确)

  • 问题内容: 我找到了在PHP中对字符串进行编码/解码的示例。起初它看起来非常好,但是不会起作用:-( 有人知道问题出在哪里吗? 结果是: 加密: 解密: 问题答案: 并且 在您的代码中未定义。查看有效的解决方案( 但不安全! ): 停! 这个例子是 不安全的! 不要使用它! **但是此代码中还有其他问题,使其变得不安全,尤其是使用ECB(这不是_加密_模式,只能在其上定义加密模式的构造块)。

  • 我用java加密一个单词,但用php解密时遇到了问题。 以下是我如何在android中创建密钥: 下面是我如何在android中使用生成的公钥加密单词: 然后我在android中将加密字符串转换为Bas64: 在php中,我解码base64字符串: 获取私钥: 最后,我尝试用php解密这个字符串: 我得到的错误是: 警告:openssl_private_decrypt():密钥参数不是有效的私钥.

  • 客户端(4.2.1)应用程序通过请求向(5.6)API发送公钥。此API使用符合的加密数据,然后使用OpenSSL public encryption和的客户端公钥加密AES加密的密钥。它将通过编码的数据发送回客户端android应用程序,客户端android应用程序将加密数据。我已经设置了一个基本的PHP测试脚本来测试整个过程,这是预期的工作。 目前,我正在客户端Android应用程序中实现解密

  • 本文向大家介绍PHP加密解密函数详解,包括了PHP加密解密函数详解的使用技巧和注意事项,需要的朋友参考一下 分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: 解密代码如下: 辅助函数: 使用如下所示: 以上就是为大家分享的php加密解密函数,希望大家喜欢,可以应用到自己的学习中。