when I try to encrypt using openssl_encrypt PHP I get square spaces at the end decrypted data which is shown in attached image
My API response is getting failure due to getting extra characters during decryption done by .NET side..
How can i resolve this issue please help
C#
public static string Decrypt(String encryptedText, String VendorKey, String Token)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(VendorKey,Token)));
}
private static byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateDecryptor()
.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
public static string Encrypt(String plainText, String VendorKey, String Token)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(VendorKey, Token)));
}
private static byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public static RijndaelManaged GetRijndaelManaged(String VendorKey, String Token)
{
var keyBytes = new byte[32];
var ivBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(VendorKey Token);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
var ivKeyBytes = Encoding.UTF8.GetBytes(VendorKey);
Array.Copy(ivKeyBytes, ivBytes, Math.Min(ivBytes.Length, ivKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.Zeros,
KeySize = 256,
BlockSize = 128,
Key = keyBytes,
IV = ivKeyBytes
};
}
So can help me to resolve this issue
CodePudding user response:
When using the sample data you provided, encryption with the .NET code:
string vendorKey = "DG4k0oKkPN7PQZZo";
string token = "761289";
string pt = @"{""prospectNo"":""SL1000000"",""paymentRequestDateFrom"":""2020-05-28"",""paymentRequestDateTo"":""2020-06-02"",""merchantTransactionId"":""7"",""callerReferenceNo"":""3""}";
string ct = Encrypt(pt, vendorKey, token);
Console.WriteLine(ct);
returns the following ciphertext:
RWbX8Xm7afBORxy462DB2Pnfu63BAt7dnKYQi1xafLuW3kHX8NjDxMxXwXHmVtJgCeOLG6edSvEEaqKbpVsR7bdfwZGLbxwfVCoOc2722fV3d8XtBfnC5PH6pwhfXwk60YAdeSOfN93a/LtL6QdV1w9XA531 wRkuHom1MehOO3DBb/b1VttZYwqx6ybZdq9EGEyzqt7hZx jppBrxzCcg==
The PHP code below:
<?php
$cipher = "AES-256-CBC";
$array = json_encode(array(
"prospectNo"=> "SL1000000",
"paymentRequestDateFrom"=>"2020-05-28",
"paymentRequestDateTo"=>"2020-06-02",
"merchantTransactionId"=> "7",
"callerReferenceNo"=>"3"
)
);
$token = "761289";
$vendorKey = "DG4k0oKkPN7PQZZo";
$key = substr(str_pad($vendorKey . $token, 32, "\0"), 0, 32);
$iv = substr(str_pad($vendorKey, 16, "\0"), 0, 16);
$encrypted_data = openssl_encrypt(zeroPad($array, 16), $cipher, $key, OPENSSL_ZERO_PADDING, $iv);
print($encrypted_data . "\n");
function zeroPad($text, $bs) {
$pad = ($bs - strlen($text) % $bs) % $bs;
return ($pad > 0) ? $text . str_repeat("\0", $pad) : $text;
}
?>
gives the same ciphertext and is thus the PHP counterpart you are looking for, i.e. under the premise that the API can process the data encrypted by the .NET code, it must also process the data encrypted by the PHP code.
As expected, this ciphertext is decrypted into the correct plaintext by the .NET code. The hex encoded plaintext also reveals that the .NET code does not remove the padding bytes (note the 8 0x00 bytes at the end):
string vendorKey = "DG4k0oKkPN7PQZZo";
string token = "761289";
string ct = "RWbX8Xm7afBORxy462DB2Pnfu63BAt7dnKYQi1xafLuW3kHX8NjDxMxXwXHmVtJgCeOLG6edSvEEaqKbpVsR7bdfwZGLbxwfVCoOc2722fV3d8XtBfnC5PH6pwhfXwk60YAdeSOfN93a/LtL6QdV1w9XA531 wRkuHom1MehOO3DBb/b1VttZYwqx6ybZdq9EGEyzqt7hZx jppBrxzCcg==";
string dt = Decrypt(ct, vendorKey, token);
Console.WriteLine("Plaintext: " dt);
Console.WriteLine("Plaintext, hex: " Convert.ToHexString(Encoding.UTF8.GetBytes(dt)));
with the output:
Plaintext: {"prospectNo":"SL1000000","paymentRequestDateFrom":"2020-05-28","paymentRequestDateTo":"2020-06-02","merchantTransactionId":"7","callerReferenceNo":"3"}
Plaintext, hex: 7B2270726F73706563744E6F223A22534C31303030303030222C227061796D656E74526571756573744461746546726F6D223A22323032302D30352D3238222C227061796D656E745265717565737444617465546F223A22323032302D30362D3032222C226D65726368616E745472616E73616374696F6E4964223A2237222C2263616C6C65725265666572656E63654E6F223A2233227D0000000000000000
The PHP code posted in this answer differs from your original PHP code essentially only in a more general derivation of $key
and $iv
(but this makes no difference for the vendorKey
used here) and the padding. The original PHP code applied the default PKCS#7 padding used by openssl_encrypt()
, while the current PHP code applies Zero padding.
Specifically, for the current plaintext, this means that the original PHP code padded with 0x0808080808080808, while the current PHP code pads with 0x0000000000000000. Since the .NET code does not remove the padding, the padding bytes are still present even when using the current PHP code (just with different values).