AES加密解密算法(前端后端互通)对应js python php和java版本

AES加密解密算法(前端后端互通)对应js python php和java版本

已知一段由AES加密的密文是U2FsdGVkX18LfWnkT9me/BDUQ4sLCjl251XbCr+NMn9M5nJ/TyIKH7AMrpQA874e 秘钥是 codelife

使用的是cryptoJS v3版本 解密算法是


        // 解密函数
        function decrypt(ciphertext, key) {
            var decrypted = CryptoJS.AES.decrypt(ciphertext, key);
            return decrypted.toString(CryptoJS.enc.Utf8);
        }

        // 示例使用
        var ciphertext = 'U2FsdGVkX18LfWnkT9me/BDUQ4sLCjl251XbCr+NMn9M5nJ/TyIKH7AMrpQA874e';
        var key = 'codelife';
        var result = decrypt(ciphertext, key);
        console.log(result);

需要根据JS版本的解密算法实现java python php 版本 方便后端的操作

对应的java版本

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;

public class AESDecryptor {

    public static String decrypt(String ciphertext, String key) throws Exception {
        byte[] cipherData = Base64.getDecoder().decode(ciphertext);
        byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, key.getBytes(StandardCharsets.UTF_8), md5);
        SecretKeySpec keySpec = new SecretKeySpec(keyAndIV[0], "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(keyAndIV[1]);

        byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decryptedData = cipher.doFinal(encrypted);

        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    private static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {
        int digestLength = md.getDigestLength();
        int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;
        byte[] generatedData = new byte[requiredLength];
        int generatedLength = 0;

        try {
            md.reset();

            while (generatedLength < keyLength + ivLength) {
                if (generatedLength > 0)
                    md.update(generatedData, generatedLength - digestLength, digestLength);
                md.update(password);
                if (salt != null)
                    md.update(salt, 0, 8);
                md.digest(generatedData, generatedLength, digestLength);

                for (int i = 1; i < iterations; i++) {
                    md.update(generatedData, generatedLength, digestLength);
                    md.digest(generatedData, generatedLength, digestLength);
                }

                generatedLength += digestLength;
            }

            byte[][] result = new byte[2][];
            result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);
            if (ivLength > 0)
                result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

            return result;
        } catch (DigestException e) {
            throw new RuntimeException(e);
        } finally {
            Arrays.fill(generatedData, (byte)0);
        }
    }

    public static void main(String[] args) {
        try {
            String ciphertext = "U2FsdGVkX18LfWnkT9me/BDUQ4sLCjl251XbCr+NMn9M5nJ/TyIKH7AMrpQA874e";
            String key = "codelife";
            String decrypted = decrypt(ciphertext, key);
            System.out.println("解密结果: " + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果
在这里插入图片描述

对应的PHP版本

    <?php

    function decrypt($ciphertext, $key) {
        $data = base64_decode($ciphertext);
        $salt = substr($data, 8, 8);
        $ct = substr($data, 16);

        $rounds = 3;
        $data00 = $key.$salt;
        $md5_hash = array();
        $md5_hash[0] = md5($data00, true);
        $result = $md5_hash[0];

        for ($i = 1; $i < $rounds; $i++) {
            $md5_hash[$i] = md5($md5_hash[$i - 1].$data00, true);
            $result .= $md5_hash[$i];
        }

        $key = substr($result, 0, 32);
        $iv  = substr($result, 32, 16);

        return openssl_decrypt($ct, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    }

    $ciphertext = 'U2FsdGVkX18LfWnkT9me/BDUQ4sLCjl251XbCr+NMn9M5nJ/TyIKH7AMrpQA874e';
    $key = 'codelife';

    $decrypted = decrypt($ciphertext, $key);
    echo $decrypted;

运行结果

在这里插入图片描述

对应的python版本

from Crypto.Cipher import AES
from Crypto.Hash import MD5
import base64

def derive_key_and_iv(password, salt, key_length, iv_length):
    d = d_i = b''
    while len(d) < key_length + iv_length:
        d_i = MD5.new(d_i + password + salt).digest()
        d += d_i
    return d[:key_length], d[key_length:key_length+iv_length]

def decrypt_aes(ciphertext, password):
    ciphertext = base64.b64decode(ciphertext)
    if ciphertext[:8] != b'Salted__':
        raise ValueError("Invalid ciphertext format")
    salt = ciphertext[8:16]
    ciphertext = ciphertext[16:]
    key, iv = derive_key_and_iv(password.encode(), salt, 32, 16)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(ciphertext)
    padding_length = decrypted[-1]
    return decrypted[:-padding_length].decode('utf-8')

# 示例代码
if __name__ == "__main__":
    key = 'codelife'
    ciphertext = "U2FsdGVkX18LfWnkT9me/BDUQ4sLCjl251XbCr+NMn9M5nJ/TyIKH7AMrpQA874e"
    decrypted_data = decrypt_aes(ciphertext, key)
    print(f"Decrypted data: {decrypted_data}")

运行结果
在这里插入图片描述

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值