Java与php的AES加解密的互通(代码)

//====================php 代码:

function encrypt($plaintext, $key) {
    $iv = openssl_random_pseudo_bytes(16); // 生成随机 IV
    $ciphertext = openssl_encrypt($plaintext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($iv . $ciphertext); // 结果包含 IV
}


function decrypt($ciphertext, $key) {
    $ciphertext = base64_decode($ciphertext, true);
    if ($ciphertext === false) {
        die("密文 Base64 解码失败!");
    }

    $iv = substr($ciphertext, 0, 16);
    $data = substr($ciphertext, 16);

    if (strlen($iv) !== 16) {
        die("IV 长度错误!");
    }
    if (strlen($key) !== 32) {
        die("Key 长度错误!");
    }

    $decrypted = openssl_decrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    if ($decrypted === false) {
        die("解密失败,可能是 Key 或填充模式不匹配!");
    }

    return $decrypted;
}

$key = hash('sha256', "mysecurekey1234567890123456", true);
$encrypted = encrypt("Hello, world!1111111111", $key);
var_dump($encrypted);
//$encrypted = "mQD8JGA6mbG+srM/eiVBfaHzCnYydacqEwE1wnnyJ8UUVQDq8bdmZ0agGqlPSFJT"; // Java 端加密数据
$decrypted = decrypt($encrypted, $key);
var_dump($decrypted);


//====================java代码:

import lombok.SneakyThrows;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

public class AESUtil {
    // 生成 16 字节的随机 IV
    private static byte[] generateIV() {
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        return iv;
    }

    // 计算 SHA-256 作为 32 字节密钥(与 PHP 兼容)
    private static byte[] processKey(String key) throws Exception {
        MessageDigest sha = MessageDigest.getInstance("SHA-256");
        return sha.digest(key.getBytes(StandardCharsets.UTF_8)); // 计算 SHA-256
    }

    // AES-256-CBC 加密
    public static String encrypt(String plaintext, String key) throws Exception {
        byte[] keyBytes = processKey(key); // 计算 SHA-256 作为密钥
        byte[] iv = generateIV(); // 生成 16 字节的随机 IV

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(iv));

        byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));

        // Base64 编码 (IV + 密文)
        byte[] finalEncrypted = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, finalEncrypted, 0, iv.length);
        System.arraycopy(encrypted, 0, finalEncrypted, iv.length, encrypted.length);

        return Base64.getEncoder().encodeToString(finalEncrypted);
    }

    // AES-256-CBC 解密
//    public static String decrypt(String encryptedBase64, String key) throws Exception {
//        byte[] encryptedData = Base64.getDecoder().decode(encryptedBase64);
//
//        // 拆分 IV 和密文
//        byte[] iv = new byte[16];
//        byte[] encrypted = new byte[encryptedData.length - 16];
//        System.arraycopy(encryptedData, 0, iv, 0, 16);
//        System.arraycopy(encryptedData, 16, encrypted, 0, encrypted.length);
//
//        IvParameterSpec ivSpec = new IvParameterSpec(iv);
//        SecretKeySpec secretKey = new SecretKeySpec(processKey(key), "AES");
//
//        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
//
//        byte[] decrypted = cipher.doFinal(encrypted);
//        return new String(decrypted);
//    }



    // AES-256-CBC 解密
    public static String decrypt(String encryptedBase64, String key) throws Exception {
        byte[] encryptedData = Base64.getDecoder().decode(encryptedBase64);

        // 拆分 IV 和密文
        byte[] iv = Arrays.copyOfRange(encryptedData, 0, 16);
        byte[] encrypted = Arrays.copyOfRange(encryptedData, 16, encryptedData.length);

        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        SecretKeySpec secretKey = new SecretKeySpec(processKey(key), "AES"); // 计算 SHA-256 作为密钥

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

        byte[] decrypted = cipher.doFinal(encrypted);
        return new String(decrypted, StandardCharsets.UTF_8);
    }

    @SneakyThrows
    public  static String urldecode(String strUrl) {
        String decodedStr = URLDecoder.decode(strUrl, "UTF-8");
        return  decodedStr;
    }

    public static void main(String[] args) {
        try {
            String key = "mysecurekey1234567890123456"; // PHP 代码里用于计算 SHA-256
            String plaintext = "Hello, world!222222222";

            String encrypted = encrypt(plaintext, key);
            System.out.println("加密后:" + encrypted);
            // 测试 PHP 生成的密文是否能解密
            //encrypted = "q+jS851UmhFmk83hTtCW/H09Ct2eRpFyDsIbNDfjsrvKcmMeHkY8FeFd54Bh35ERs5ayizBXaJf0Y6qTQP4LNe/QhH4zkD9iJayPUKFQWdDqXHnq3WNZKfQoFVo8pcs9qjGhxRchnj+BNgciPS7mGpLm5yI2rwNUAfDwlo6t5SY=";
            encrypted = urldecode("71RR99AQfeho6teZ7hyKCH6KKZ6Dii%2BTO3JFX%2F%2BsX9bJKcGG6vyD44pjSiKF%2FAeKskeM%2B4rdF8RG0hsRMPwaDluki7eYVmhfJiuhTaGCjMnhtaZzWDa%2Bl43yw%2FG2TaTyaAtxTAqoF65CC6oCUWDX3eG%2FwgfTQNgN19vzQAFQbGaZt18PT%2F17CGAsFk%2FhxixV");
            String decrypted = decrypt(encrypted, key);
            System.out.println("解密后:" + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

经测试,可用!
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值