我花了一周的时间才找到用 Java、PHP 和 Java Script 编写的 aes-128-cbc 的工作代码。我不得不在各种网站上搜索很多。最后通过多次点击和试用,下面的代码为我解决了。既加密又解密。用Java加密;在 PHP 或 JavaScript 中解密,在 PHP 中加密;用 Java 或 JavaScript 解密,用 JavaScript 加密 用 PHP 或 Java 解密。所有选项都会起作用
Key 的长度为 16 位,包含字母数字值。使用相同的密钥来加密和解密数据。 IV 是加密时要传递的 16 位字母数字的随机值。
加解密PHP代码:
function encrypt($key, $iv, $data) {
static $OPENSSL_CIPHER_NAME = "aes-128-cbc"; //Name of OpenSSL Cipher
static $CIPHER_KEY_LEN = 16; //128 bits
if (strlen($key) < $CIPHER_KEY_LEN) {
$key = str_pad("$key", $CIPHER_KEY_LEN, "0"); //0 pad to len 16
} else if (strlen($key) > $CIPHER_KEY_LEN) {
$key = substr($str, 0, $CIPHER_KEY_LEN); //truncate to 16 bytes
}
$encodedEncryptedData = base64_encode(openssl_encrypt($data, $OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, $iv));
$encodedIV = base64_encode($iv);
$encryptedPayload = $encodedEncryptedData.":".$encodedIV;
return $encryptedPayload;
}
function decrypt($key, $data) {
// $key = $request['key'];
// $data = $request['data'];
static $OPENSSL_CIPHER_NAME = "aes-128-cbc"; //Name of OpenSSL Cipher
static $CIPHER_KEY_LEN = 16; //128 bits
if (strlen($key) < $CIPHER_KEY_LEN) {
$key = str_pad("$key", $CIPHER_KEY_LEN, "0"); //0 pad to len 16
} else if (strlen($key) > $CIPHER_KEY_LEN) {
$key = substr($str, 0, $CIPHER_KEY_LEN); //truncate to 16 bytes
}
$parts = explode(':', $data); //Separate Encrypted data from iv.
$decryptedData = openssl_decrypt(base64_decode($parts[0]), $OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, base64_decode($parts[1]));
return $decryptedData;
}
用于加密和解密的 Java 代码
import android.util.Base64;
import android.util.Log;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Java_AES_Cipher {
private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
private static int CIPHER_KEY_LEN = 16; //128 bits
/**
* Encrypt data using AES Cipher (CBC) with 128 bit key
*
*
* @param key - key to use should be 16 bytes long (128 bits)
* @param iv - initialization vector
* @param data - data to encrypt
* @return encryptedData data in base64 encoding with iv attached at end after a :
*/
public static String encrypt(String key, String iv, String data) {
try {
if (key.length() < Java_AES_Cipher.CIPHER_KEY_LEN) {
int numPad = Java_AES_Cipher.CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > Java_AES_Cipher.CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("ISO-8859-1"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");
Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String base64_EncryptedData = Base64.encodeToString(encryptedData, Base64.DEFAULT);
String base64_IV = Base64.encodeToString(iv.getBytes("ISO-8859-1"), Base64.DEFAULT);
base64_EncryptedData = base64_EncryptedData.replaceAll(System.getProperty("line.separator"), "");
base64_IV = base64_IV.replaceAll(System.getProperty("line.separator"), "");
Log.i("Java_AES_Cipher","Encrypted data is "+ base64_EncryptedData + ":" + base64_IV);
return base64_EncryptedData + ":" + base64_IV;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/**
* Decrypt data using AES Cipher (CBC) with 128 bit key
*
* @param key - key to use should be 16 bytes long (128 bits)
* @param data - encrypted data with iv at the end separate by :
* @return decrypted data string
*/
public static String decrypt(String key, String data) {
try {
if (key.length() < Java_AES_Cipher.CIPHER_KEY_LEN) {
int numPad = Java_AES_Cipher.CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > Java_AES_Cipher.CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
String[] parts = data.split(":");
if (parts.length<2)
{
Log.i("Java_AES_Cipher","Length "+ parts.length);
return data;
}
IvParameterSpec iv = new IvParameterSpec(Base64.decode(parts[1], Base64.DEFAULT));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ISO-8859-1"), "AES");
Cipher cipher = Cipher.getInstance(Java_AES_Cipher.CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decodedEncryptedData = Base64.decode(parts[0], Base64.DEFAULT);
byte[] original = cipher.doFinal(decodedEncryptedData);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
用于加密和解密的 Java 脚本代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
function encrypt (messageText,key, iv){
var message = messageText;
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted = CryptoJS.AES.encrypt(
message,key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
this.encrypted = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
console.log('encrypted:'+encrypted);
return encrypted;
}
function decrypt(keyBase64, messagebase64) {
const digest = messagebase64.split(':');
const crypttext = CryptoJS.enc.Base64.parse(digest[0])
const ivBase64 = CryptoJS.enc.Base64.parse(digest[1])
const decrypted = CryptoJS.AES.decrypt(
{
ciphertext: crypttext
},
CryptoJS.enc.Utf8.parse(keyBase64),
{
iv: ivBase64,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
console.log('decrypted: '+decrypted.toString(CryptoJS.enc.Utf8));
return decrypted.toString(CryptoJS.enc.Utf8);
}