Most of the time we come across a scenario where we want something that is encrypted in Java, that requires to be decrypted by PHP or vice versa. In this article, we will build a Java class that encrypt-decrypt the input string and the same class in PHP which also encrypt-decrypts the input string and produces the same result.
AES Encryption Decryption in Java
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class JavaPHPCompatibleEncryption {
private static String CIPHER_NAME = "AES/CBC/PKCS5PADDING";
private static int CIPHER_KEY_LEN = 16; //128 bits
public static final String ENCRYPTION_KEY = "u7k3g4e6n7t6h7l2"; // 128 bit key
public static final String ENCRYPTION_IV = "9876543210fedcba"; // 16 bytes IV
public static String encryptToHex(String key, String iv, String data) {
try {
if (key.length() < JavaPHPCompatibleEncryption.CIPHER_KEY_LEN) {
int numPad = JavaPHPCompatibleEncryption.CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > JavaPHPCompatibleEncryption.CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
IvParameterSpec initVector = new IvParameterSpec(iv.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(JavaPHPCompatibleEncryption.CIPHER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initVector);
byte[] encryptedData = cipher.doFinal((data.getBytes()));
String base64_EncryptedData = Base64.getEncoder().encodeToString(encryptedData);
String base64_IV = Base64.getEncoder().encodeToString(iv.getBytes("UTF-8"));
return asciiToHex(base64_EncryptedData + ":" + base64_IV);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decryptFromHex(String key, String hexdata) {
try {
if (key.length() < JavaPHPCompatibleEncryption.CIPHER_KEY_LEN) {
int numPad = JavaPHPCompatibleEncryption.CIPHER_KEY_LEN - key.length();
for(int i = 0; i < numPad; i++){
key += "0"; //0 pad to len 16 bytes
}
} else if (key.length() > JavaPHPCompatibleEncryption.CIPHER_KEY_LEN) {
key = key.substring(0, CIPHER_KEY_LEN); //truncate to 16 bytes
}
String data = hexToAscii(hexdata);
String[] parts = data.split(":");
IvParameterSpec iv = new IvParameterSpec(Base64.getDecoder().decode(parts[1]));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(JavaPHPCompatibleEncryption.CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decodedEncryptedData = Base64.getDecoder().decode(parts[0]);
byte[] original = cipher.doFinal(decodedEncryptedData);
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static String asciiToHex(String asciiStr) {
char[] chars = asciiStr.toCharArray();
StringBuilder hex = new StringBuilder();
for (char ch : chars) {
hex.append(Integer.toHexString((int) ch));
}
return hex.toString();
}
private static String hexToAscii(String hexStr) {
StringBuilder output = new StringBuilder("");
for (int i = 0; i < hexStr.length(); i += 2) {
String str = hexStr.substring(i, i + 2);
output.append((char) Integer.parseInt(str, 16));
}
return output.toString();
}
public static void main(String[] args) {
String input = "Hi, I am using AES Enc-Dec Algorithm";
String enc = encryptToHex(ENCRYPTION_KEY, ENCRYPTION_IV, input);
String dec = decryptFromHex(ENCRYPTION_KEY,enc);
System.out.println("Input Text : " + input);
System.out.println("Encrypted Text : " + enc);
System.out.println("Decrypted Text : " + dec);
}
}
The output of the above Java class –
Input Text : Hi, I am using AES Enc-Dec Algorithm
Encrypted Text : 314e4d51397a2f566d6947375a7137574c646a7a6747784137587a694c78586d375555485a70587249596b6b5a2f736b6e3550426b38695136634f716a7830693a4f5467334e6a55304d7a49784d475a6c5a474e6959513d3d
Decrypted Text : Hi, I am using AES Enc-Dec Algorithm
AES Encryption Decryption in PHP
<?php
class JavaPHPCompatibleEncryption {
private static $OPENSSL_CIPHER_NAME = "aes-128-cbc"; //Name of OpenSSL Cipher
private static $CIPHER_KEY_LEN = 16; //128 bits
static function encrypt($key, $iv, $data) {
if (strlen($key) < JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN) {
$key = str_pad("$key", JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN, "0"); //0 pad to len 16
} else if (strlen($key) > JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN) {
$key = substr($str, 0, JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN); //truncate to 16 bytes
}
$encodedEncryptedData = base64_encode(openssl_encrypt($data, JavaPHPCompatibleEncryption::$OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, $iv));
$encodedIV = base64_encode($iv);
$encryptedPayload = $encodedEncryptedData.":".$encodedIV;
return bin2hex($encryptedPayload);
}
static function decrypt($key, $data) {
if (strlen($key) < JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN) {
$key = str_pad("$key", JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN, "0"); //0 pad to len 16
} else if (strlen($key) > JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN) {
$key = substr($str, 0, JavaPHPCompatibleEncryption::$CIPHER_KEY_LEN); //truncate to 16 bytes
}
$dataStr = hex2bin($data);
$parts = explode(':', $dataStr); //Separate Encrypted data from iv.
$decryptedData = openssl_decrypt(base64_decode($parts[0]), JavaPHPCompatibleEncryption::$OPENSSL_CIPHER_NAME, $key, OPENSSL_RAW_DATA, base64_decode($parts[1]));
return $decryptedData;
}
}
$iv = '9876543210fedcba';
$key = 'u7k3g4e6n7t6h7l2';
$inputData = "Hi, I am using AES Enc-Dec Algorithm";
echo "Input Text : $inputData <br><br>";
$encrypted = JavaPHPCompatibleEncryption::encrypt($key, $iv, $inputData);
echo "Encrypted Text: $encrypted <br><br>";
$decryptedPayload = JavaPHPCompatibleEncryption::decrypt($key, $encrypted);
echo "Decrypted Text: $decryptedPayload <br><br>";
?>
The output of the above PHP class –
Input Text : Hi, I am using AES Enc-Dec Algorithm
Encrypted Text: 314e4d51397a2f566d6947375a7137574c646a7a6747784137587a694c78586d375555485a70587249596b6b5a2f736b6e3550426b38695136634f716a7830693a4f5467334e6a55304d7a49784d475a6c5a474e6959513d3d
Decrypted Text: Hi, I am using AES Enc-Dec Algorithm
Here you can see that from both the languages, the same encrypted string is been generated. We can use this in the cross-platform application, where encryption is done at one end and decrypted at another end.
Jkoder.com Tutorials, Tips and interview questions for Java, J2EE, Android, Spring, Hibernate, Javascript and other languages for software developers