I have the following Java code
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.sec
Since you are interested in the decryption of an encrypted string in which the encryption was done with the Java encryptEK
-method and the decryption should be done with the PHP decrypt
-method (or vice versa) I ignore the code of the main
-method (which isn't very clear to me) and I focus on the porting of the both Java-methods, encryptEK
and decrypt
, to PHP-methods.
The Java encryptEK
-method takes a plain text and a key as byte array, encrypts the plain text using AES (256-ECB) and encodes the encrypted text using Base64 encoding. A possible PHP-counterpart is:
public function encrypt($data = '', $key = NULL) {
if($key != NULL && $data != ""){
$method = "AES-256-ECB";
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA);
$result = base64_encode($encrypted);
return $result;
}else{
return "String to encrypt, Key is required.";
}
}
Note: The ECB-mode doesn't use an IV.
The Java decrypt
-method takes a base64 encoded string, decodes it and then decrypts it. A possible PHP-counterpart is
public function decrypt($data="", $key = NULL) {
if($key != NULL && $data != ""){
$method = "AES-256-ECB";
$dataDecoded = base64_decode($data);
$decrypted = openssl_decrypt($dataDecoded, $method, $key, OPENSSL_RAW_DATA);
return $decrypted;
}else{
return "Encrypted String to decrypt, Key is required.";
}
}
The both Java-methods, encodeBase64String
and decodeBase64StringTOByte
, which use the java.util.Base64
-class are not consumed by the Java-methods encryptEK
and decrypt
. Instead of that, the corresponding methods of the org.apache.commons.codec.binary.Base64
-class (e.g. https://commons.apache.org/proper/commons-codec/download_codec.cgi) are consumed. For this reason, I do not take any further notice of both methods.
In the Java reference code no 256bit-AES key is examplarily generated, but a random key is typically generated in the following way:
KEYGEN.init(256);
SecretKey secretKey = KEYGEN.generateKey();
byte[] key = secretKey.getEncoded();
In PHP this is done with
$key = random_bytes(32);
For a mixed encryption/decryption-testing (e.g. Java/PHP) on both sides the same key has to be used. E.g., this key is provided in Java:
byte[] key = "This is a 256 bits = 32 byte key".getBytes(Charsets.UTF_8);
and in PHP:
$key = mb_convert_encoding("This is a 256 bits = 32 byte key", "UTF-8");
Test 1: Encrypt/Decrypt with Java (using a random generated key)
Plain text: The quick brown fox jumps over the lazy dog
Randomly generated key (hex): 20e9c191374b688e74e68ab6c969109e84c5c8e059d84f16f2beb07a7545cbc8
Encrypted text (base64 encoded): ZWOnSYErRxRRtqoVFTLVQMT329pOFHzN1gPDMuiZt0zFpt4n2TF/L54RB21zhVUa
Decrypted text: The quick brown fox jumps over the lazy dog
Test 2: Encrypt/Decrypt with PHP (using a random generated key)
Plain text: The quick brown fox jumps over the lazy dog
Randomly generated key (hex): eecd40c21e2a395f3aa3baeac19bfc8dcee04ea6e07f02dca7069397a487824f
Encrypted text (base64 encoded): 8wjusOED9TTXHjyEqvmGExLATVlvhg3hXEBHQ6Ku3Fos2OrYKbF+4XdO6cD9JJA5
Decrypted text: The quick brown fox jumps over the lazy dog
Possible encryption and decryption portion:
$key = random_bytes(32);
echo bin2hex($key);
$atomAES = new AtomAES();
$encrypt = $atomAES->encrypt("The quick brown fox jumps over the lazy dog", $key);
echo $encrypt;
$decrypt = $atomAES->decrypt($encrypt, $key);
echo $decrypt;
Test 3: Encrypt with Java/Decrypt with PHP (using the concrete key above)
Plain text: The quick brown fox jumps over the lazy dog
Encrypted text (base64 encoded) with Java: /XjXJc5dNk6p/h2HL8MVmmWG8Vd0Ud2x1QQWwmIQr9OG/PXZ0AzsIIMV1YmvMJho
Decrypted text with PHP: The quick brown fox jumps over the lazy dog
Possible decryption portion:
$key = mb_convert_encoding("This is a 256 bits = 32 byte key", "UTF-8");
$atomAES = new AtomAES();
$decrypt = $atomAES->decrypt("/XjXJc5dNk6p/h2HL8MVmmWG8Vd0Ud2x1QQWwmIQr9OG/PXZ0AzsIIMV1YmvMJho", $key);
echo $decrypt;
Test 4: Encrypt with PHP/Decrypt with Java (using the concrete key above)
Plain text: The quick brown fox jumps over the lazy dog
Encrypted text (base64 encoded) with PHP: /XjXJc5dNk6p/h2HL8MVmmWG8Vd0Ud2x1QQWwmIQr9OG/PXZ0AzsIIMV1YmvMJho
Decrypted text with Java: The quick brown fox jumps over the lazy dog
Possible encryption portion:
$key = mb_convert_encoding("This is a 256 bits = 32 byte key", "UTF-8");
$atomAES = new AtomAES();
$encrypt = $atomAES->encrypt("The quick brown fox jumps over the lazy dog", $key);
echo $encrypt;
EDIT:
The counterpart to the code in the main-method is (in combination with your sample):
$encKey = mb_convert_encoding("VEMwcCYfFpsrXQVIFTDrA/2zP/5PYOY6JC1XEkEcLGSk/klt+HqHzGSr781Yznku", "UTF-8");
$asp_secret = mb_convert_encoding("DTosv9G179D0cY1985Uh2eF6ND80C95L", "UTF-8");
atomAES = new AtomAES();
$enc_key = $atomAES->decrypt($encKey, $asp_secret);
$enc_asp_secret = $atomAES->encrypt($asp_secret, base64_decode(base64_encode($enc_key)));
//$enc_asp_secret = $atomAES->encrypt($asp_secret, $enc_key);
echo "asp secret encrypted:\n".mb_convert_encoding($enc_asp_secret, "UTF-8")."\n";
Note: The PHP expression base64_decode(base64_encode($enc_key))
is equivalent to $enc_key
, thus you can also replace it with the line currently commented out. The only reason I coded it is because it is also coded in the Java code. Here decodeBase64StringTOByte(encodeBase64String(enc_key)
is equivalent
to enc_key
. That's because the one method is the inverse of the other method.
If you run the above code the output is
asp secret encrypted:
zAnTcjmAezfdzrWGixyfwmb8cM0otrsmwJ8+cNDs48Axh9hYgBtCJyeSE9tCvEBz
You can alternatively define a third method of the AtomAES
-class:
public function main(){
$encKey = mb_convert_encoding("VEMwcCYfFpsrXQVIFTDrA/2zP/5PYOY6JC1XEkEcLGSk/klt+HqHzGSr781Yznku", "UTF-8");
$asp_secret = mb_convert_encoding("DTosv9G179D0cY1985Uh2eF6ND80C95L", "UTF-8");
$enc_key = $this->decrypt($encKey, $asp_secret);
$enc_asp_secret = $this->encrypt($asp_secret, base64_decode(base64_encode($enc_key)));
//$enc_asp_secret = $this->encrypt($asp_secret, $enc_key);
echo "asp secret encrypted:\n".mb_convert_encoding($enc_asp_secret, "UTF-8")."\n";
}
which can be called with
$atomAES = new AtomAES();
$atomAES->main();