The test code from Powershell:
$theKey = (21,123,21,3,141,13,14,253,151,13,11,241,36,21,18,17,61,11,21,9,5,21,17,28)
$theString = "Test String"
$Secure = ConvertTo-SecureString -String $theString -AsPlainText -Force
$encrypted = ConvertFrom-SecureString -SecureString $Secure -Key $theKey
How do I use openssl to decrypt the string? Or is there other better method? Sample PHP i tried:
$encrypted_string ="76492d1116743f0423413b16050a5345MgB8AHAAMwBnAE4AMwBsADcASQBLAEIANQBPAFAAKwBaAGgAUgBXAGwAaQBoAGcAPQA9AHwAZQA4ADUAOAA3ADEAOABhADMAOQBlADcAMABlADEAZAAzAGMAMgBjADEANQA3ADMANABjAGQAZgA4ADcAMwAyAGQANQBmAGIAMAA5ADUAYwA2ADcAOQBiADIAMAA3ADQANAA3ADYAMAAwAGIAYgA2AGQAZgAwAGYAMgBkADUANgA=";
$cipher = "aes-192-cbc";
$iv_size = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($iv_size);
$theKey = (21,123,21,3,141,13,14,253,151,13,11,241,36,21,18,17,61,11,21,9,5,21,17,28);
$decrypted_data = openssl_decrypt($encrypted_string, $cipher, $theKey, 0, $iv);
$encrypted
from the Powershell code has the following format and encoding (from this post):
The encrypted data consists of the concatenation of a 16 bytes hex encoded prefix followed by a Base64 encoded string:
76492d1116743f0423413b16050a5345 MgB8AHAAMwBnAE4AMwBsADcASQBLAEIANQBPAFAAKwBaAGgAUgBXAGwAaQBoAGcAPQA9AHwAZQA4ADUAOAA3ADEAOABhADMAOQBlADcAMABlADEAZAAzAGMAMgBjADEANQA3ADMANABjAGQAZgA4ADcAMwAyAGQANQBmAGIAMAA5ADUAYwA2ADcAOQBiADIAMAA3ADQANAA3ADYAMAAwAGIAYgA2AGQAZgAwAGYAMgBkADUANgA=
The prefix is not needed for decryption. The Base64 encoded string corresponds (after Base64 decoding) to a UTF-16LE encoded byte sequence.
Decoding of the UTF-16LE encoded byte sequence gives the following string:
2|p3gN3l7IKB5OP+ZhRWlihg==|e858718a39e70e1d3c2c15734cdf8732d5fb095c679b207447600bb6df0f2d56
This string consists of three parts, separated by |
. The first part is not needed for decryption, the second part is the Base64 encoded IV, the third part is the hex encoded ciphertext.
After separating IV and ciphertext the ciphertext can be decrypted with the IV and the 24 bytes key using AES-192.
The decrypted plaintext corresponds to the UTF-16LE encoded original plaintext string.
A possible PHP implementation is:
<?php
// Decode key
$keyArr = [21,123,21,3,141,13,14,253,151,13,11,241,36,21,18,17,61,11,21,9,5,21,17,28];
$key = pack('C*', ...$keyArr);
// Decode data
$dataFromPS = '76492d1116743f0423413b16050a5345MgB8AHAAMwBnAE4AMwBsADcASQBLAEIANQBPAFAAKwBaAGgAUgBXAGwAaQBoAGcAPQA9AHwAZQA4ADUAOAA3ADEAOABhADMAOQBlADcAMABlADEAZAAzAGMAMgBjADEANQA3ADMANABjAGQAZgA4ADcAMwAyAGQANQBmAGIAMAA5ADUAYwA2ADcAOQBiADIAMAA3ADQANAA3ADYAMAAwAGIAYgA2AGQAZgAwAGYAMgBkADUANgA==';
$dataPayloadB64 = substr($dataFromPS, 32);
$dataPayloadUtf16le = base64_decode($dataPayloadB64);
$dataPayloadUtf8 = mb_convert_encoding($dataPayloadUtf16le, 'utf-8', 'utf-16le');
// Separate IV and ciphertext
$dataPayloadArr = explode('|', $dataPayloadUtf8);
$ivB64 = $dataPayloadArr[1];
$ctHex = $dataPayloadArr[2];
$iv = base64_decode($ivB64);
$ct = hex2bin($ctHex);
// Decrypt
$cipher = "aes-192-cbc";
$decryptedDataUtf16le = openssl_decrypt($ct, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$decryptedDataUtf8 = mb_convert_encoding($decryptedDataUtf16le, 'utf-8', 'utf-16le');
// Output
print("Payload, UTF-16LE: " . $dataPayloadUtf16le . "\n");
print("Payload, UTF-8: " . $dataPayloadUtf8 . "\n");
print("IV, Base64: " . $ivB64 . "\n");
print("Ciphertext, hex: " . $ctHex . "\n");
print("Decrypted, UTF-16LE: " . $decryptedDataUtf16le . "\n");
print("Decrypted, UTF-8: " . $decryptedDataUtf8 . "\n");
?>
The PHP code gives the following output:
Payload, UTF-16LE: 2 | p 3 g N 3 l 7 I K B 5 O P + Z h R W l i h g = = | e 8 5 8 7 1 8 a 3 9 e 7 0 e 1 d 3 c 2 c 1 5 7 3 4 c d f 8 7 3 2 d 5 f b 0 9 5 c 6 7 9 b 2 0 7 4 4 7 6 0 0 b b 6 d f 0 f 2 d 5 6
Payload, UTF-8: 2|p3gN3l7IKB5OP+ZhRWlihg==|e858718a39e70e1d3c2c15734cdf8732d5fb095c679b207447600bb6df0f2d56
IV, Base64: p3gN3l7IKB5OP+ZhRWlihg==
Ciphertext, hex: e858718a39e70e1d3c2c15734cdf8732d5fb095c679b207447600bb6df0f2d56
Decrypted, UTF-16LE: T e s t S t r i n g
Decrypted, UTF-8: Test String