I have a Java code snippet for encryption/decryption using AES, and I need to convert it to PHP for use in my web application. I've tried a few approaches but haven't been successful. Below is the Java code I'm trying to convert:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void main(String[] args) {
String encryptedData = "lmncpiedimdofipgnokfeppgfncimkac";
String secretKey = "0123456789ABCDEF"; // 16-character key
String iv = "0123456789ABCDEF"; // 16-character initialization vector
try {
String decryptedData = decrypt(encryptedData, secretKey, iv);
System.out.println("Decrypted data: " + decryptedData);
} catch (Exception e) {
System.err.println("Error while decrypting: " + e.getMessage());
e.printStackTrace();
}
}
public static String decrypt(String decData, String secretKey, String vector) throws Exception {
byte[] raw = secretKey.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes("utf-8"));
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = decodeBytes(decData);
byte[] original = cipher.doFinal(encrypted1);
return new String(original, "utf-8");
}
public static String encodeBytes(byte[] bytes) {
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
}
return strBuf.toString();
}
public static byte[] decodeBytes(String str) {
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i += 2) {
char c = str.charAt(i);
bytes[i / 2] = (byte) ((c - 'a') << 4);
c = str.charAt(i + 1);
bytes[i / 2] += (c - 'a');
}
return bytes;
}
}
I've attempted to convert this Java code to PHP, but I'm encountering issues, particularly with the decryption logic. Below is the PHP code I've tried:
<?php
$encryptedData = "lmncpiedimdofipgnokfeppgfncimkac";
$secretKey = "0123456789ABCDEF"; // 16-character key
$iv = "0123456789ABCDEF"; // 16-character initialization
try {
$decryptedData = decrypt($encryptedData, $secretKey, $iv);
echo "Decrypted data: " . $decryptedData;
} catch (Exception $e) {
echo "Error while decrypting: " . $e->getMessage();
$e->getTrace();
}
function decrypt($decData, $secretKey, $vector) {
$cipher = "AES-128-CBC";
$options = 0;
$decData = hex2bin($decData);
$vector = hex2bin($vector);
$decryptedData = openssl_decrypt($decData, $cipher, $secretKey, $options, $vector);
if ($decryptedData === false) {
throw new Exception('Decryption failed: ' . openssl_error_string());
}
return $decryptedData;
}
?>
It does not return any value.
In your PHP code there are several bugs:
OPENSSL_RAW DATA
.hex2bin()
).decodeBytes()
does not implement a simple hex decoding, i.e. hex2bin($decData)
is wrong. You need to port decodeBytes()
from Java to PHP.Your PHP decryption code with possible fixes:
<?php
$encryptedData = "lmncpiedimdofipgnokfeppgfncimkac";
$secretKey = "0123456789ABCDEF"; // 16-character key
$iv = "0123456789ABCDEF"; // 16-character initialization
try {
$decryptedData = decrypt($encryptedData, $secretKey, $iv);
echo "Decrypted data: " . $decryptedData;
} catch (Exception $e) {
echo "Error while decrypting: " . $e->getMessage();
$e->getTrace();
}
function decodeBytes($data) {
$res = '';
for ($i = 0; $i < strlen($data); $i+=2){
$high = (ord($data[$i]) - ord('a')) << 4;
$low = ord($data[$i + 1]) - ord('a');
$res .= chr($high + $low);
}
return $res;
}
function decrypt($decData, $secretKey, $vector) {
$cipher = "AES-128-CBC";
$options = OPENSSL_RAW_DATA; // Fix 1
//$vector = hex2bin($vector); // Fix 2
$decData = decodeBytes($decData); // Fix 3
$decryptedData = openssl_decrypt($decData, $cipher, $secretKey, $options, $vector);
if ($decryptedData === false) {
throw new Exception('Decryption failed: ' . openssl_error_string());
}
return $decryptedData;
}
?>
With these changes, decryption works and returns the plaintext hello world
for your test data.
Security: