Convert VB.NET AES encoding to PHP using openssl_decrypt - php

Currently I'm working on integration of external service wrote in VB.NET.
This service send me a string with some information encrypted with below function (this is a cut and past from the external service developer that send me the code)
Public Function Decode(ByVal S As String, ByVal chiave As String, ByVal iv As String) As String
Dim rjm As RijndaelManaged = New RijndaelManaged
rjm.KeySize = 128
rjm.BlockSize = 128
rjm.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(chiave)
rjm.IV = System.Text.ASCIIEncoding.ASCII.GetBytes(iv)
Try
Dim input() As Byte = System.Convert.FromBase64String(S)
Dim output() As Byte = rjm.CreateDecryptor.TransformFinalBlock(input, 0, input.Length)
Return System.Text.Encoding.UTF8.GetString(output)
Catch ex As System.Exception
Return S
End Try
End Function
if I decode the string with below mcrypt function everything work as expected:
$mcrypt_cipher = MCRYPT_RIJNDAEL_128;
$mcrypt_mode = MCRYPT_MODE_CBC;
$iv= '1234567891011121';
$key = '1234567891011121';
$message= base64_decode($message);
$message = rtrim(mcrypt_decrypt($mcrypt_cipher, $key, $message, $mcrypt_mode, $iv), "\0");;
But i'm unable to obtain same result with openssl_decrypt. the function always fail with false as result, below the code:
$result = openssl_decrypt(
base64_decode($message),
'AES-128-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
I'm pretty sure that the problem is related to some padding that i missing.. but I don't understand where the problem is exactly.
UPDATE1 -
I correct the code, both $iv and $key are strings i forgot the ' both are of 16Bytes = 128Bits

Related

AES 256 with PKCS7 padding

The GST Council has approved the implementation of ‘e-Invoicing’ or ‘electronic invoicing’ of Business to Business (B2B) invoices to GST System if company turnover is greater that 500 crore. Ref of gst portal API :einv-apisandbox.nic.in/index.html
I have to decrypt the encrypted SEK using APP key and encode json data using decrypted SEK to post for Einvoice Generation and i found sample code for java and C# and i have converted in PHP but unfortunately failed to get desired output
In my case encrypted SEK is: oRvKfBtmgNTSuk/oXUhiLOjXi45jiWA2oKNxhhQM3UH2o/32YWGLbUjK1/dohPe3
APP key: fao1PoKaLgd11xMrWTiL2cggAfx9QMwM
Symmetric decryption (AES) (in java)
public static String decrptyBySyymetricKey(String encryptedSek, byte[] appKey)
{
Key aesKey = new SecretKeySpec(appKey, "AES"); // converts bytes(32 byte random generated) to key
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // encryption type = AES with padding PKCS5
cipher.init(Cipher.DECRYPT_MODE, aesKey); // initiate decryption type with the key
byte[] encryptedSekBytes = Base64.decodeBase64(encryptedSek); // decode the base64 encryptedSek to bytes
byte[] decryptedSekBytes = cipher.doFinal(encryptedSekBytes); // decrypt the encryptedSek with the initialized cipher containing the key(Results in bytes)
String decryptedSek = Base64.encodeBase64String(decryptedSekBytes); // convert the decryptedSek(bytes) to Base64 StriNG
return decryptedSek; // return results in base64 string
}catch(Exception e) {
return "Exception; "+e;
}
}
Symmetric encryption (AES) (in java)
public static string EncryptBySymmetricKey(string text, string sek)
{
//Encrypting SEK
try
{
byte[] dataToEncrypt = Convert.FromBase64String(text);
var keyBytes = Convert.FromBase64String(sek);
AesManaged tdes = new AesManaged();
tdes.KeySize = 256;
tdes.BlockSize = 128;
tdes.Key = keyBytes;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
pICryptoTransform encrypt__1 = tdes.CreateEncryptor();
byte[] deCipher = encrypt__1.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
tdes.Clear();
string EK_result = Convert.ToBase64String(deCipher);
return EK_result;
}
catch (Exception ex)
{
throw ex;
}
}
Symmetric encryption (AES) (in PHP)
function encrypt($data, $key)
{
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, hash('SHA256', $key, true), $data, MCRYPT_MODE_ECB));
}
Symmetric decryption (AES) (in PHP)
function decrypt($key, $str)
{
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, hash('SHA256', $key, true), $str, MCRYPT_MODE_ECB);
$pad = ord($str[($len = strlen($str)) - 1]);
$len = strlen($str);
$pad = ord($str[$len-1]);
return base64_encode( substr($str, 0, strlen($str) - $pad));
}
The decryption of the session key (SEK) with the AppKey is possible in PHP as follows:
function decrptyBySymmetricKey($encSekB64, $appKey) {
$sek = openssl_decrypt($encSekB64, "aes-256-ecb", $appKey, 0); // the SEK
$sekB64 = base64_encode($sek); // the Base64 encoded SEK
return $sekB64;
}
The encryption of data with the SEK is possible in PHP as follows:
function encryptBySymmetricKey($dataB64, $sekB64){
$data = base64_decode($dataB64); // the data to encrypt
$sek = base64_decode($sekB64); // the SEK
$encDataB64 = openssl_encrypt($data, "aes-256-ecb", $sek, 0); // the Base64 encoded ciphertext
return $encDataB64;
}
Both functions can be tested with the following data:
$appKey = 'fao1PoKaLgd11xMrWTiL2cggAfx9QMwM'; // the 32 bytes AppKey
$encSekB64 = 'oRvKfBtmgNTSuk/oXUhiLOjXi45jiWA2oKNxhhQM3UH2o/32YWGLbUjK1/dohPe3'; // the Base64 encoded encrypted SEK
$dataB64 = 'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw=='; // the base64 encoded data
$sekB64 = decrptyBySymmetricKey($encSekB64, $appKey); // the Base64 encoded SEK
$encDataB64 = encryptBySymmetricKey($dataB64, $sekB64); // the Base64 encoded ciphertext
echo $sekB64 . "\n"; // zVoede7m2nnvMHcWYIfKhrvsilSFEZYiltJmxVQQnAQ=
echo $encDataB64; // JS+hxYf64FMHThrhoIejqk3VjGwFw+GTYzUyVKc6GEOLKERVuvaNY91zPdo829r0
The Java method decryptBySymmetricKey returns with
byte[] appKey = "fao1PoKaLgd11xMrWTiL2cggAfx9QMwM".getBytes(StandardCharsets.UTF_8);
String encSekB64 = "oRvKfBtmgNTSuk/oXUhiLOjXi45jiWA2oKNxhhQM3UH2o/32YWGLbUjK1/dohPe3";
String sekB64 = decryptBySymmetricKey(encSekB64, appKey);
the same value for the Base64 encoded SEK (zVoede7m2nnvMHcWYIfKhrvsilSFEZYiltJmxVQQnAQ=).
Likewise, the C# method EncryptBySymmetricKey (erroneously labeled in the question as Java function) returns with
string dataB64 = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==";
string sekB64 = "zVoede7m2nnvMHcWYIfKhrvsilSFEZYiltJmxVQQnAQ=";
string encDataB64 = EncryptBySymmetricKey(dataB64, sekB64);
the same value for the Base64 encoded ciphertext (JS+hxYf64FMHThrhoIejqk3VjGwFw+GTYzUyVKc6GEOLKERVuvaNY91zPdo829r0).
Note:
The deprecated mcrypt is not used. Instead openssl is applied.
Besides the security aspect, openssl has the advantage over mcrypt, that PKCS7 padding is implicitly used, analogous to the C#/Java code. mcrypt applies Zero padding, so a user defined padding was necessary, which is obsolete with openssl.
The key is not derived from the passed key via SHA256, but applied directly, analogous to the C#/Java code.
You also might need to try with postman tool. I achieve the same and able to connect the NIC system but as per the document they have provided it's not possible to achieve the same encryption using OpenSSL or other encryption tool.
Now I moved on to GSP based API connectivity solution you might check this stuff from
https://github.com/sujianalytics/gst-e-invoicing-sap
It's open source but not relevant for your issue, might need to upgrade little bit as per your requirement.

Decrypting in PHP encrypted in VB

I have to decrypt data in PHP that was encrypted IN VB.
When I decrypt numbers I have no problem, but when I decrypt text I only get the first 8 characters and then random.
This is the key "a1R#f7D$"
This is what I am trying to decrypt:
LwEe+sQCn63m9kjtqiy67ul5R1Ng7SZPVO4YYxQvZtUZBwNTb+Ey0qCNsrczI4jN
And I get this:
{Preinsc]hn��m�ȕ�!��^߇� $! �E&;�e^#S�)6Ui�4�
I tried with MCRYPT_RIJNDAEL_256 and ecb but none worked to me.
function decrypt($data ){
$encryption_key = "a1R#f7D$";
$data = urldecode($data);
$key = md5(utf8_encode($encryption_key), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
This is the function that encrypted this:
Public Shared Function tryingTripleDes (ByVal value As String, ByVal key As String) As String
Dim des As New Security.Cryptography.TripleDESCryptoServiceProvider
des.IV des.IV = New Byte(7) {}
Dim pdb As New Security.Cryptography.PasswordDeriveBytes(key, New Byte(-1) {})
des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, New Byte(7) {})
Dim ms As New IO.MemoryStream((value.Length * 2) - 1)
Dim encStream As New Security.Cryptography.CryptoStream(ms, des.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
Dim plainBytes As Byte() = Text.Encoding.UTF8.GetBytes(value)
encStream.Write(plainBytes, 0, plainBytes.Length)
encStream.FlushFinalBlock()
Dim encryptedBytes(CInt(ms.Length - 1)) As Byte
ms.Position = 0
ms.Read(encryptedBytes, 0, CInt(ms.Length))
encStream.Close()
Return Convert.ToBase64String(encryptedBytes)
End Function
This would typically happen if the ciphertext is CBC encrypted with an all zero byte IV. Other modes may also work, but CBC is by far the most likely. Your key and cipher are correct, otherwise you will only get garbage in return - certainly not legible text.
Note that MCRYPT_RIJNDAEL_256 is not even AES, so trying that is kind of useless, you should use MCRYPT_RIJNDAEL_128 with a correctly sized key to get AES.
I won't go into the security of CBC with a zero byte IV and deprecated cipher like 3DES. It's not a good idea, especially not for transport security.

Decrypt Access token using PHP for C# Encryption

I have an API URL with specific access token which was encrypted with C#(Below Code) and I want to Decrypt it using PHP post request by passing access token to parameters. Can anyone help me out to solve this problem.
Thanks in Advance!!
C# Code for Encryption:
private String AES_encrypt(String Input)
{
var aes = new RijndaelManaged();
aes.KeySize = 256;
aes.BlockSize = 256;
aes.Padding = PaddingMode.PKCS7;
aes.Key =Convert.FromBase64String("QdZx1B0ZIcLK7DPNRK09wc/rjP4WnxtE");
aes.IV = Convert.FromBase64String("hBSE4tn6e/5c3YVKFZ54Iisi4MiDyCO0HJO+WZBeXoY=");
var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
byte[] xXml = Encoding.UTF8.GetBytes(Input);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = ms.ToArray();
}
String Output = Convert.ToBase64String(xBuff);
return Output;
}
So far I tried to decrypt it with the below code
function strippadding($string)
{
$slast = ord(substr($string, -1));
$slastc = chr($slast);
$pcheck = substr($string, -$slast);
if(preg_match("/$slastc{".$slast."}/", $string)){
$string = substr($string, 0, strlen($string)-$slast);
return $string;
} else {
return false;
}
}
function decrypt($string)
{
$key = base64_decode("DZR");
$iv = base64_decode("Shravan");
$string = base64_decode($string);
return strippadding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $string, MCRYPT_MODE_CBC, $iv));
}
Fill out the items below:
Use this key and iv that are below.
key = QdZx1B0ZIcLK7DPNRK09wc/rjP4WnxtE
iv= hBSE4tn6e/5c3YVKFZ54Iisi4MiDyCO0HJO+WZBeXoY=
Run some text through your AES_encrypt() function and whatever comes out paste on the next line.
encrypted text = put your encrypted text here.
$xXml = openssl_decrypt(
$Output, #openssl_decrypt works with base64 encoded data
'AES-256-CBC',
base64_decode("QdZx1B0ZIcLK7DPNRK09wc/rjP4WnxtE"), #key
OPENSSL_RAW_DATA,
base64_decode("hBSE4tn6e/5c3YVKFZ54Iisi4MiDyCO0HJO+WZBeXoY=") #IV
);
Now $xXml is the binary form of the input string in UTF-8 encoded.
And make sure openssl is included in your PHP build.
You have not provided me with any encrypted text to be able to test this with.
Here is what I think you need to do:
In your C# code you need to change the block size to 128 bits:
aes.BlockSize = 128;
In your C# code your IV needs to be 128 bits or 16 bytes long. It needs to equal your selected block size.
So for now this needs to be your IV:
IV = HWeR102dxMjRHZlxTqL2aA==
Your key is set for 256 bits: So here is a 256 bit key:
Key = aZUEBKSsYRKA6CGQbwFwvIS8rUnW7YA2hVMNHnnf844=
C# has functions that will automatically generate a cryptographically strong string for you of a certain length. I suggest you find these functions and learn how to use them so you can generate your own keys and IVs.
Now for the PHP portion.
You should use the OpenSSL library instead of the Mcrypt library. Mcrypt is deprecated and is no longer supported. So here is an OpenSSL solution.
Since the block size is now 128 bits and the key size is 256 bits it will now be compatible with the openssl library's AES-256-CBC function.
$key = 'aZUEBKSsYRKA6CGQbwFwvIS8rUnW7YA2hVMNHnnf844='; //256 bit key.
$iv = 'HWeR102dxMjRHZlxTqL2aA=='; //128 bit IV length. The same as the block size that is set in the C#.
function decrypt($string, $key, $iv){
$cipherText = base64_decode($string); //We are going to use raw data.
return openssl_decrypt($cipherText, 'AES-256-CBC', base64_decode($key), OPENSSL_RAW_DATA, base64_decode($iv));
//Note that I did not specify no padding in the function. By default it is PKCS#7 which is what is set in the C# code.
}
The best I can tell this should work for you. This assumption is predicated on the fact that your AES_encrypt() is working correctly and that you have OpenSSL on your machine. Which you probably do.
Hope it helps!

.Net and PHP Rijndael encryption not matching

At first i thought it was the padding since mcrypt uses zero padding but i changed the php to use PKCS7 and get the same exact results
Can anyone help? I think it has something to do with the padding in the php
Test output from .Net:
Key: d88f92e4fa27f6d45b49446c7fc76976
Text: Testing123
Encrypted: /DMkj7BL9Eu2LMxKhdGT+A==
Encrypted after base64 decode: ?3$??K?K?,?J???
Decrypted: Testing123
Test output from PHP:
Key: d88f92e4fa27f6d45b49446c7fc76976
Text: Testing123
Encrypted: K+ke5FNI5T6F6B/XvDF494+S8538Ze83cFz6v1FE89U=
Encrypted after base64 decode: +éäSHå>…è×¼1x÷’óüeï7p\ú¿QDóÕ
Decrypted: Testing123����������������������
PHP:
class rijndael{
var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
var $mcrypt_mode = MCRYPT_MODE_CBC;
function decrypt($pass, $encrypted)
{
$encrypted = base64_decode($encrypted);
$key = $this->getkey($pass);
$iv = $this->getiv($pass);
$decrypted = mcrypt_decrypt($this->mcrypt_cipher, $key, $encrypted, $this->mcrypt_mode, $iv);
$block = mcrypt_get_block_size($this->mcrypt_cipher, $this->mcrypt_mode);
$pad = ord($decrypted[($len = strlen($decrypted)) - 1]);
return substr($decrypted, 0, strlen($decrypted) - $pad);
}
function encrypt($pass, $decrypted)
{
$key = $this->getkey($pass);
$iv = $this->getiv($pass);
$block = mcrypt_get_block_size($this->mcrypt_cipher, $this->mcrypt_mode);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$encrypted = mcrypt_encrypt($this->mcrypt_cipher, $key, $decrypted, $this->mcrypt_mode, $iv);
return base64_encode($encrypted);
}
function getkey($passphrase)
{
$L1 = base64_encode(hash("sha256", $passphrase, true));
$L2 = $passphrase.$L1;
return hash("sha256", $L2, true);
}
function getiv($passphrase)
{
$L1 = base64_encode(md5($passphrase));
$L2 = $passphrase.$L1;
return md5($L2);
}
}
VB .Net:
Public Class RijnDael
Public Shared Function Decrypt(ByVal sData As String, ByVal sKey As String)
Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
Return Decrypt(bytData, sKey)
End Function
Public Shared Function Decrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
Dim bytResult As Byte()
Using oRM As New System.Security.Cryptography.RijndaelManaged
oRM.KeySize = 256
oRM.Key = GeKey(strPass)
oRM.IV = GetIV(strPass)
oRM.Mode = CipherMode.CBC
oRM.Padding = PaddingMode.PKCS7
Using oMS As New MemoryStream(bytData)
Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateDecryptor, Security.Cryptography.CryptoStreamMode.Read)
Dim TempDecryptArr As Byte()
ReDim TempDecryptArr(bytData.Length)
Dim decryptedByteCount As Integer
decryptedByteCount = oCS.Read(TempDecryptArr, 0, bytData.Length)
'
ReDim bytResult(decryptedByteCount)
Array.Copy(TempDecryptArr, bytResult, decryptedByteCount)
'
oCS.Close()
End Using
oMS.Close()
End Using
End Using
Return bytResult
End Function
Public Shared Function Encrypt(ByVal sData As String, ByVal sKey As String)
Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
Return Encrypt(bytData, sKey)
End Function
Public Shared Function Encrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
Dim bytResult As Byte()
Using oRM As New Cryptography.RijndaelManaged
oRM.KeySize = 256
oRM.Key = GeKey(strPass)
oRM.IV = GetIV(strPass)
oRM.Mode = CipherMode.CBC
oRM.Padding = PaddingMode.PKCS7
Using oMS As New MemoryStream
Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateEncryptor, Cryptography.CryptoStreamMode.Write)
oCS.Write(bytData, 0, bytData.Length)
oCS.FlushFinalBlock()
bytResult = oMS.ToArray()
oCS.Close()
End Using
oMS.Close()
End Using
End Using
Return bytResult
End Function
Private Shared Function GeKey(ByVal strPass As String) As Byte()
Dim bytResult As Byte()
'Generate a byte array of required length as the encryption key.
'A SHA256 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
Using oSHA256 As New Cryptography.SHA256Managed
Dim L1 As String = System.Convert.ToBase64String(oSHA256.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
Dim L2 As String = strPass & L1
bytResult = oSHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
oSHA256.Clear()
End Using
Return bytResult
End Function
Private Shared Function GetIV(ByVal strPass As String) As Byte()
Dim bytResult As Byte()
'Generate a byte array of required length as the iv.
'A MD5 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
Using oMD5 As New Cryptography.MD5CryptoServiceProvider
Dim L1 As String = System.Convert.ToBase64String(oMD5.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
Dim L2 As String = strPass & L1
bytResult = oMD5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
oMD5.Clear()
End Using
Return bytResult
End Function
End Class
The problems in your two pieces of code are:
Use Rijndael-128 with a key and block size of 16 bytes / 128 bit in both the .NET and the PHP code. For Rijndael-256, your code generates an IV with the wrong length. And I don't know how to use AES-256 in PHP (key length of 32 bytes / 256 bits, block size of 16 bytes / 128 bit).
Use of MD5: In the PHP code, add a second parameter true to the md5() function (in two places) so the result is binary data and not a hexadecimal string.
In the encrypt() function in your PHP code, replace the variable $str with $decrypted (in two places). $str is never assigned a value and never used, so the padding has no effect.
If you fix these problems, then both programs will return the result:
Encrypted: /DMkj7BL9Eu2LMxKhdGT+A==
I haven't tried to decrypt it.
For starters the 2 bits of code will create different initialization vectors (PHP is using sha256, and .net md5). And you're not truncating the PHP output by then first null char. There are several potential char set issues in the code too.

Decrypt string in php which was encrypted with aspEncrypt

I need to communicate with a asp platform that uses the aspEncrypt from persits.
Can anyone provide an example how to decode a string with PHP and mcrypt that was created via the aspEncrypt routines.
An example page of aspEncrypt is available at this link:
http://support.persits.com/encrypt/demo_text.asp
So if I use the text "Test" and the key "test" it provides an base64 encoded string. I need a php example that convert this encoded string back to the text "Test" with usage of key "test".
This is how i finally solved it:
Expectation:
Key is known
IV is known (in my case, first 32 characters of encoded data)
Encrypted Text is known
In my special case all received data hex encoded.
This means IV and encrypted text.
function decrypt($sString, $sIv, $sKey, $iCipherAlg) {
$sDecrypted = mcrypt_decrypt($iCipherAlg, $sKey, $sString, MCRYPT_MODE_CBC, $sIv);
return trim($sDecrypted);
}
function hex2bin($sData) {
$iLen = strlen($sData);
$sNewData = '';
for($iCount=0;$iCount<$iLen;$iCount+=2) {
$sNewData .= pack("C",hexdec(substr($sData,$iCount,2)));
}
return $sNewData;
}
$sKey = 'this is my key';
// first 32 chars are IV
$sIv = hex2bin(substr($sEncodedData, 0, 32));
$sEncodedData = substr($sEncodedData, 32);
$sEncodedRaw = hex2bin($sEncodedData);
$sDecrypted = decrypt($sEncodedRaw, $sIv, $sKey, MCRYPT_RIJNDAEL_128);
A corresponding encryption works like that:
$sIv = mcrypt_create_iv(mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$sKey = 'this is my key';
$sContent = 'a lot of content';
$sEncrypted = bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $sKey, $sContent, MCRYPT_MODE_CBC, $sIv));
$sFullEncodedText = bin2hex($sIv) . $sEncrypted;
I encountered an old VBScript project which was encrypting strings with AspEncrypt like this:
Function EncryptString(data, base64Iv)
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContextEx("Microsoft Enhanced RSA and AES Cryptographic Provider", "", True)
Set Key = Context.GenerateKeyFromPassword("secret encryption password", calgSHA512, calgAES256)
Set IVblob = CM.CreateBlob
IVblob.Base64 = base64Iv
Key.SetIV IVblob
Set Blob = Key.EncryptText(data)
EncryptString = Blob.Base64 & ":" & base64Iv
End Function
Based on the arguments to GenerateKeyFromPassword, a binary key is created by hashing the password with SHA-512, and data is encrypted with the aes-256-cbc algorithm. The random Base64-encoded initialization vector is appended to the encrypted value after a colon.
This can be replicated in PHP using the OpenSSL extension:
class Aes256Cbc
{
private string $algo = 'aes-256-cbc';
private string $key;
private int $ivLen;
public function __construct(string $password)
{
$this->key = hash('sha512', $password, true);
$this->ivLen = openssl_cipher_iv_length($this->algo);
}
public function encrypt(string $data): string
{
$iv = random_bytes($this->ivLen);
$ciphertext = openssl_encrypt($data, $this->algo, $this->key, OPENSSL_RAW_DATA, $iv);
return base64_encode($ciphertext) . ':' . base64_encode($iv);
}
public function decrypt(string $encrypted): string
{
[$ctPart, $ivPart] = explode(':', $encrypted);
$iv = base64_decode($ivPart);
$ciphertext = base64_decode($ctPart);
return openssl_decrypt($ciphertext, $this->algo, $this->key, OPENSSL_RAW_DATA, $iv);
}
}
Example usage:
$aes = new Aes256Cbc("secret encryption password");
$decrypted = $aes->decrypt($someValue);
Note: if AspEncrypt was used without setting an initialization vector, the IV will be sequence of null bytes. This fixed IV could be generated in the above PHP class as follows:
$iv = str_repeat("\0", $this->ivLen);
It depends on which cipher it uses, take a look at mcrypt as long as you know the cipher and key it should be easy to decrypt.
If you know the cipher and mode used by the encryption, the function mcrypt_decrypt can decrypt it.
http://uk3.php.net/manual/en/function.mcrypt-decrypt.php

Categories