I encrypt some data in PHP with openssl and try to decrypt it with the C# .NET cryptography methods. The result is a data block that's correct in size, but the data itself is incorrect. I'm sure I'm missing something trivial, but I've been at it for days for now and I can't seem to figure it out. (The reverse, encrypting in C# and decrypting in PHP works fine, so the methods provided are compatible.)
PHP code:
function encrypt($data, $key)
{
$method = "AES-256-CBC";
$ivSize = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivSize);
$encrypted = openssl_encrypt($data, $method, $key, 0, $iv);
return array(strlen($data), $iv, $encrypted);
}
[Code for handling other stuff here.]
if (!empty($_GET["upKey"]))
{
$upKey = str_replace(" ", " ", $_GET["upKey"]);
if (openssl_private_decrypt(base64_decode($upKey), $decryptedUpKey, $privateKey))
{
$toEncrypt = file_get_contents("filename");
$encryptionData = array(0, 0, 0);
$encryptionData = encrypt($toEncrypt, $decryptedUpKey);
echo $encryptionData[0]."\n".base64_encode($encryptionData[1])."\n".base64_encode($encryptionData[2])."\n\nKey: ".base64_encode($decryptedUpKey)."\nPlaintext: ".bin2hex($toEncrypt);
}
}
C# code:
byte[] upKey = new byte[32];
for (int i=0; i<32; i )
{
upKey[i] = (byte) rand.Next(0, 256);
}
byte[] encryptedUpKey = rsa.Encrypt(upKey, false);
string finalResult = await client.GetStringAsync("http://www.websitename.com/pagename.php?password=" Convert.ToBase64String(password) "&upKey=" Convert.ToBase64String(encryptedUpKey));
Console.WriteLine("HTTP RESULT:\n\n" finalResult "\n");
string[] encryptionInfo = finalResult.Split("\n");
int length = Int32.Parse(encryptionInfo[0]);
byte[] IV = Convert.FromBase64String(encryptionInfo[1]);
byte[] data = Convert.FromBase64String(encryptionInfo[2]);
Console.WriteLine("\nLOCAL DATA:\n\nLen: " length "\nIV: " Convert.ToBase64String(IV) "\nKey: " Convert.ToBase64String(upKey) "\nData: " Convert.ToBase64String(data) "\n");
Console.WriteLine(binaryToString(decrypt(data, upKey, length, IV), false));
client is and HttpClient instance. The actual decryption method:
static byte[] decrypt(byte[] data, byte[] key, int? predefinedLength = null, byte[]? predefinedIV = null)
{
try
{
int length;
if (predefinedLength == null)
{
length = BitConverter.ToInt32(data, 0);
}
else
{
length = (int) predefinedLength;
}
byte[] IV = new byte[16];
if (predefinedIV == null)
{
for (int i = 4; i < 20; i )
{
IV[i - 4] = data[i];
}
}
else
{
IV = predefinedIV;
}
byte[] actualData;
if (predefinedIV != null || predefinedLength != null)
{
actualData = data;
}
else
{
actualData = new byte[data.Length - 20];
for (int i = 0; i < actualData.Length; i )
{
actualData[i] = data[i 20];
}
}
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = IV;
if (predefinedIV != null || predefinedLength != null)
{
aes.Mode = CipherMode.CBC;
}
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(actualData))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (BinaryReader br = new BinaryReader(cs))
{
return br.ReadBytes(length);
}
}
}
}
}
catch (CryptographicException ce)
{
//Console.WriteLine(ce.Message);
return new byte[0];
}
}
Output:
HTTP RESULT:
656 69X3YXiijHWxqgwI81Sj6g== QjRlazllS2EyaFBndHljUzdzbk9EbWxkb29renp6aWRMMTV4OHdJTXRtRzR3cnQvVkZsT2dJbk14c2MzdEFnd24wcFJJcS9weHR4bzFGMVJCVHF6NE1xU1BrQURrQnhxQkdET1RxdnkrUWZTU2c2NVVoU1h1MHN6blZVTXdQenhYcXkxdUIyT3lFYjJPaHh3Z2xZZ0VkWTViUFpwYVpCOFl1ZFIrTUVWNVV3VCtpWDF1SmVOeDVza1g1NHUxUG1WNXM3dkpKSklSYUl6VW5mSXR4QVNrNDU0NmFhcEt2K3ZCengyYWdFcTkyb2hZLzYwT3hPeTdybUJhclB3ZkhVYmVraW5vbCtLYUQ3aHA5NUVkMjdpOFluMXlJRDVkWnAzejBJankxRWhxQkNILzR0cFNkQVNBZDN1Wm9WV3RxTFVyVEZCYTFCT0JQcUp3Z3F1anJudXJsQ3VMSGNIdEIyeW4rODg1Sk8wd1JXTXA3R3hoOE45a1MvR09VdGpxSjNTUUd1b1Vya1U5NE0yZXFnd1R3UHZzbjdsUE5wb2VBODN3TUhTRkpSdkIxYkdMdDY4dkpPZHZQQ1JzWGtDTEY2VmZYY3ZMWDJHWllWZHlNNmtBYVpIWVFaZW5xQXQ5bUo1VEplQjlWd0VTYWp2U09DSUpJa1I5VXVlYmRINmRmWjV2WFVVZ2xWamJlLzNWMUxJVHJmZEVXYjIrSEFJVTM5OTc4S0daRG1WREplRFJpZ3lDSGdmMWc3bk5VeEwzcmxlNDVVQ0c4R2EwRDlFcUtIMWxQWllzUzV6YlJVYWNhTktxd2dvRUVVL3RSeTIzK0w5K0JoSll0WlZ1VGFLNlpJSWc4Q1JPbDVIbWU1N0cvYmE3dFdwZkhZY2J0TlV5c0xacWY5RmxIUXY3aks1OE04TWlkK29HL2lXRWFZdUt4WUZ5UEFtU0pwTnhSVTVBVzdhaVU0ZlBWenZBZkhDMDM4VEdnL3dRdVF1cGpjQzBESVB2SEVvRjFjQjdLZ3hJL1g2RmJEakFuRllaWDBJdFhxTlZ4c2h1SDREZkhKWllPZThJRDNvMXpIZkIyZmdUY3NaTXVvZTIrQk93WGdKSCsyWlJ3U3dSa0pIbVRGelZ0ZVdpUloxTVVhNW80cS9aU0xkQ1BObDdVMEVyQlVqUkxLM2FFT0lTR2ZmVVhzOUI1enk=
Key: Vhxi VF1PcWDi/IkP1Is1r86QBX6a/g8cdugW/JM/m0= Plaintext: 3800380030003000300030003000300036003000300043003400380044004600320043003900300037003200300035003800390043003800340045004600370045003600370043003300390038004600300045004200370046003100360032004600420044004300370031004100300046004400410033004400410044004600370041004100330031004400380044003200460041003000330037004300430032004100410041004200410044003000420043004100330045003400310039003900320038004200320037004100310031003800350034003100460034004300330032003400330044004100460039003700320037003800320031003100430038003200430046003700440030004600430039003700300038004600350038003800410045004200460035003800320036003600390046004600380039003800330035004400460038003300450037003600450033003800420043003600360044003700460034004300320036003900330030003400450033003800450037004300410043003600430031004300340042003800420031004400380046004600460044003200380037004500320042004400460030003900330038003700350038004500390035004100370036004500390044003000360039004300330034003500360037003300420030003600310045003400390043003500390041004500300032003600360033004200410038004200300039003300370031003700440033003100380034003200370044003600360031003600410043003900380033004600380035004300310039004100370043003600420033003800440033003600380033003200450036004600320031003300350038003900390041003500320042004200460036003500450038003500
LOCAL DATA:
Len: 656 IV: 69X3YXiijHWxqgwI81Sj6g== Key: Vhxi VF1PcWDi/IkP1Is1r86QBX6a/g8cdugW/JM/m0= Data: QjRlazllS2EyaFBndHljUzdzbk9EbWxkb29renp6aWRMMTV4OHdJTXRtRzR3cnQvVkZsT2dJbk14c2MzdEFnd24wcFJJcS9weHR4bzFGMVJCVHF6NE1xU1BrQURrQnhxQkdET1RxdnkrUWZTU2c2NVVoU1h1MHN6blZVTXdQenhYcXkxdUIyT3lFYjJPaHh3Z2xZZ0VkWTViUFpwYVpCOFl1ZFIrTUVWNVV3VCtpWDF1SmVOeDVza1g1NHUxUG1WNXM3dkpKSklSYUl6VW5mSXR4QVNrNDU0NmFhcEt2K3ZCengyYWdFcTkyb2hZLzYwT3hPeTdybUJhclB3ZkhVYmVraW5vbCtLYUQ3aHA5NUVkMjdpOFluMXlJRDVkWnAzejBJankxRWhxQkNILzR0cFNkQVNBZDN1Wm9WV3RxTFVyVEZCYTFCT0JQcUp3Z3F1anJudXJsQ3VMSGNIdEIyeW4rODg1Sk8wd1JXTXA3R3hoOE45a1MvR09VdGpxSjNTUUd1b1Vya1U5NE0yZXFnd1R3UHZzbjdsUE5wb2VBODN3TUhTRkpSdkIxYkdMdDY4dkpPZHZQQ1JzWGtDTEY2VmZYY3ZMWDJHWllWZHlNNmtBYVpIWVFaZW5xQXQ5bUo1VEplQjlWd0VTYWp2U09DSUpJa1I5VXVlYmRINmRmWjV2WFVVZ2xWamJlLzNWMUxJVHJmZEVXYjIrSEFJVTM5OTc4S0daRG1WREplRFJpZ3lDSGdmMWc3bk5VeEwzcmxlNDVVQ0c4R2EwRDlFcUtIMWxQWllzUzV6YlJVYWNhTktxd2dvRUVVL3RSeTIzK0w5K0JoSll0WlZ1VGFLNlpJSWc4Q1JPbDVIbWU1N0cvYmE3dFdwZkhZY2J0TlV5c0xacWY5RmxIUXY3aks1OE04TWlkK29HL2lXRWFZdUt4WUZ5UEFtU0pwTnhSVTVBVzdhaVU0ZlBWenZBZkhDMDM4VEdnL3dRdVF1cGpjQzBESVB2SEVvRjFjQjdLZ3hJL1g2RmJEakFuRllaWDBJdFhxTlZ4c2h1SDREZkhKWllPZThJRDNvMXpIZkIyZmdUY3NaTXVvZTIrQk93WGdKSCsyWlJ3U3dSa0pIbVRGelZ0ZVdpUloxTVVhNW80cS9aU0xkQ1BObDdVMEVyQlVqUkxLM2FFT0lTR2ZmVVhzOUI1enk=
77DB03C6CC26393BC0815D0394326AAAD931C973A23A06005AE9F08C044B3C5B8932E7655A47C1B78B439F9876D50C52A0723D5F083D0CA07DDD080BD31109772785E8C6C36564C5C10C0799EB99ABDB9894A6CF310969B9A8717B8FE879E713A34C301D93D4B2271E93632272A9497A4D14B996CA0D37A17B7EF2BEF26C83044173EF76AB6730D34AB5242B8C99B9176AEE12AF17E1AB0376E315D2B5F10A8AE7BE5ED4B5391582500146C54D41162FA766A789313916B501B64A35F2220E138759C572D0B0484AB48435EF31ACB01A2CD39D7F83807FC70606C21D57AA8AA61291B1A74561A8766E21A18B7BD04BB56BCC3604CDFE5748FF9345F395B5CDD3C3F841482AE750D1ABC19DD7681C6F817987CA68D6FF91DABA10BD2A7D0981F5F035F10E53347D4AEABF6061B2237C93F57FF6DDDB822239D62A59E782EE39E6C583078E3C98F2251A1062ED09CAD2BA9F72C2CF92259E8F2C6E8BF5F11FB481B57256214690C60BDDC7BFFDB86DF1AB9C7680DDEFCAF0B9D6F43ED7829C3FACA6BF4B8DF83CC16EB3950FB6215B1B598061EAACB1403B05B0D2CF28E65E2B0A2C800ED358852D7E3CDC29BC00571FEA26CB0B20D5F3E0B79F1FF366BC19DE23596BB489D40DE112CB3823E43CA739BE9580D8D8060E7E6E445DF25F10B3C7D2987BF7002182E8D1766CEB0326BF24F97BBCE0123F557DFC63A774C42212BCD6C3DECEAE76F831EFC7FF381D1E2926DABC2A787053294445BC3895828C6AF4709CE826E326CF153050CC20C527C5A482704A1EA44A3E6BCCBAA820FA2400F3DD03E58E715260F216DC648E6C793A33CACB8A584CF7B20C4AFBBA7E56D1BB5BB089695EB4BF8C6DBF9859AD03E017873F8A18DB194165DB4F78938ABD0035236FC63D7081D7336283D120C4273CA1D7F6
As you can see, everything, IV, key, method and plaintext matches, but the decryption still fails. What am I missing?
CodePudding user response:
Alright, thanks to Topaco's kind contribution I finally found out what the issue is. I needed to set the flag OPENSSL_RAW_DATA in the openssl_encrypt call. That's all it was.