You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS端AES加密内容无法被PHP端解密的问题排查及可行对称加密实现方案请求

JS端AES加密内容无法被PHP端解密的问题排查及可行对称加密实现方案请求

Goal

I am doing a proof of concept of a symmetric key encryption. A JavaScript code will send an AES encrypted string, which I want to decrypt via PHP.

Attempt

Client-side Code

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" integrity="sha512-a+SUDuwNzXDvz4XrIcXHuCf089/iJAoN4lmrXJg18XnduKK6YlDHNRalv4yd1N40OKI80tFidF+rqTFKGPoWFQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/aes.min.js" integrity="sha512-UOtWWEXoMk1WLeC873Gmrkb2/dZMwvN1ViM9C1mNvNmQSeXpEr8sRzXLmUSha1X4x5V892uFmEjiZzUsYiHYiw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/enc-base64.min.js" integrity="sha512-m/shICarVhgGKyAmv7SlfXVinPq1eNVh4aPdBpGw6lqT3lh/hYtZJ+HaX6DuxjN8o7giM9mfpZQf314bErdGUg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script>
function encryptFlag(flag, sessionKey) {
    // Encrypt the flag using AES-128-ECB with the session key and no padding
    const hash = CryptoJS.SHA256(sessionKey);
    const encrypted = CryptoJS.AES.encrypt(flag, hash, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.NoPadding    // No padding
    });
    
    console.log("hash", hash);
    // Return the encrypted flag in hex format
    return encrypted.toString();
}

const encryptedFlag = encryptFlag(flag, key);

axios.post('/my-end-point', {
        command: 'login_current_device',
        encrypted_flag: encryptedFlag,
        user: username
    }).then(response => {
        console.log('Server response:', response.data);
        if (response.data.success) {
            window.location.href = "/collab-apex/dashboard";  // Redirect to dashboard if login successful
        } else {
            alert('decoding failed!');
        }
    }).catch(error => {
        console.error('Error during request:', error);
    });
</script>

Server-side Code

$decryptedFlag = decryptFlag($encryptedFlag, hash('sha256',$sessionKey));

function decryptFlag($encryptedFlag, $sessionKey) {
    // Decrypt using AES-128-ECB and the session key
    $decrypted = openssl_decrypt(
        base64_decode($encryptedFlag),
        'AES-128-ECB', // AES encryption mode
        $sessionKey,   // Session key as the secret key
        OPENSSL_RAW_DATA
    );

    return $decrypted;
}

Exact problem

The PHP is returning an empty string. It has the correct session key there. The encrypted flag is also correct.

Attempt to solution

First, I check with an online AES encryption/decryption tool.

This is my flag: n/ghZub%h/gh3678 (it can be any alphanumeric + symbols string, no control char).

The JavaScript, using AES 128, ECB, no padding with key PPEGFtHt9+n6z]1p gives the result:

tjjg2Sfi0D7c5Oxjb4sJ7cmbXrpic+lknjNLI3ojeO0=

But the online tool returns: JQE/sqMZCNegPJIric+RUA==, which can be decrypted by the same tool. (Un)surprisingly, the JavaScript output can't be decoded to the correct result.

If I specifically set return encrypted.toString(CryptoJS.enc.Base64); I get error :

Error during request: TypeError: r.clamp is not a function
    stringify https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/enc-base64.min.js:1
    toString https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js:1

If I do not include the base64 JS file from CDNJS, then the error is:

Error during request: TypeError: wordArray.clamp is not a function
    stringify https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.js:1311
    toString https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.js:3998

If I set return encrypted.toString(CryptoJS.enc.Hex);, the result in JavaScript is an empty string.

Back at PHP side, it is an empty string in any case; even if I use :

$decrypted = openssl_decrypt(
        $encryptedFlag, // I removed the base64decode here
        'AES-128-ECB', // AES encryption mode
        $sessionKey,   // Session key as the secret key
        OPENSSL_RAW_DATA
    );

I looked at a Stack Overflow question - and that is how I came to the idea of using a hash. Even without hashing the session key, PHP is always returning an empty string.

Session key is 16 chars long, which is 128 bit.

Question

How can I resolve this situation, so that a symmetric key cryptographic exchange works between JS and PHP?

I would like to find what is wrong in my implementation; but I am open to a different symmetric key algorithm if you provide the full code for implementation. The requirements are that

  1. it has to be symmetric key, and
  2. it has to work between JS and PHP.

Thank you.


备注:内容来源于stack exchange,提问作者Sean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:19:52