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}")
运行结果