插件窝 干货文章 Java AES加密如何用PHP7实现?

Java AES加密如何用PHP7实现?

加密 String 密钥 encrypted 319    来源:    2025-03-13

要在PHP 7中实现与Java AES加密兼容的加密和解密,你需要确保使用相同的加密算法、密钥长度、模式和填充方式。通常,Java中的AES加密使用的是AES/CBC/PKCS5Padding模式。

以下是一个示例,展示如何在PHP 7中实现与Java AES加密兼容的加密和解密。

1. Java中的AES加密示例

假设你在Java中使用以下代码进行AES加密:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AESExample {
    public static String encrypt(String key, String initVector, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String key, String initVector, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

            byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));
            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String key = "1234567890123456"; // 16 bytes key
        String initVector = "1234567890123456"; // 16 bytes IV
        String plaintext = "Hello, World!";

        String encrypted = encrypt(key, initVector, plaintext);
        System.out.println("Encrypted: " + encrypted);

        String decrypted = decrypt(key, initVector, encrypted);
        System.out.println("Decrypted: " + decrypted);
    }
}

2. PHP 7中的AES加密实现

在PHP 7中,你可以使用openssl_encryptopenssl_decrypt函数来实现与Java兼容的AES加密和解密。

<?php

function encrypt($key, $iv, $plaintext) {
    // Ensure the key and IV are 16 bytes long
    $key = substr(hash('sha256', $key, true), 0, 16);
    $iv = substr(hash('sha256', $iv, true), 0, 16);

    // Encrypt the plaintext
    $ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

    // Return the base64 encoded ciphertext
    return base64_encode($ciphertext);
}

function decrypt($key, $iv, $ciphertext) {
    // Ensure the key and IV are 16 bytes long
    $key = substr(hash('sha256', $key, true), 0, 16);
    $iv = substr(hash('sha256', $iv, true), 0, 16);

    // Decode the base64 encoded ciphertext
    $ciphertext = base64_decode($ciphertext);

    // Decrypt the ciphertext
    $plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

    return $plaintext;
}

$key = "1234567890123456"; // 16 bytes key
$iv = "1234567890123456"; // 16 bytes IV
$plaintext = "Hello, World!";

$encrypted = encrypt($key, $iv, $plaintext);
echo "Encrypted: " . $encrypted . "\n";

$decrypted = decrypt($key, $iv, $encrypted);
echo "Decrypted: " . $decrypted . "\n";

?>

3. 关键点

  • 密钥和IV长度:AES-128-CBC模式要求密钥和IV的长度为16字节。如果密钥或IV的长度不足,可以通过哈希函数(如SHA-256)来生成16字节的密钥和IV。
  • 填充方式:Java中的AES/CBC/PKCS5Padding对应PHP中的AES-128-CBC模式,PHP会自动处理PKCS7填充(PKCS7是PKCS5的超集)。
  • Base64编码:Java和PHP中的加密结果通常使用Base64编码,以便于传输和存储。

4. 测试

你可以将Java和PHP的加密结果进行对比,确保它们能够互相解密。

5. 注意事项

  • 确保密钥和IV的安全性,不要在代码中硬编码密钥和IV。
  • 在实际应用中,密钥和IV应该通过安全的方式生成和存储。

通过以上步骤,你可以在PHP 7中实现与Java AES加密兼容的加密和解密。