Reputation: 245
I got my encryption algorithm working fine and left it alone for a few months. Today I needed to use it again and somehow it broke. I have poked at it for a while and have been unable to spot what the problem is. There are no errors, it just returns junk data.
The Setup: A PHP script(that has worked in production for a long time) encrypts some string using:
function hexstr($hexstr)
{
// return pack('H*', $hexstr); also works but it's much harder to understand.
$return = '';
for ($i = 0; $i < strlen($hexstr); $i+=2) {
$return .= chr(hexdec($hexstr[$i] . $hexstr[$i+1]));
}
return $return;
}
function encrypt($str, $key)
{
$key = hexstr($key);
$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($size, MCRYPT_RAND);
return $iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC,$iv);
}
If I decrypt this on the php side it works fine.
Then the string is base64 encoded:
$encoded = base64_encode($encrypted);
Finally the C# program gets a hold of it and does the following:
....
byte[] decoded = Convert.FromBase64String(myWebText);
Decrypt(decoded)
.....
public static byte[] Decrypt(byte[] p)
{
RijndaelManaged aes128 = new RijndaelManaged();
aes128.KeySize = 128;
//aes128.BlockSize =
aes128.Padding = PaddingMode.Zeros;
aes128.Mode = CipherMode.CBC;
aes128.Key = StringToByteArray("SOMEHEXSTRING");
//pull the iv off the front of the byte array
if (p.Length <= 16)
{
Utils.ReportError("byte array too short");
return null;
}
byte[] iv = new byte[16];
Array.Copy(p, 0, iv, 0, 16);
aes128.IV = iv;
ICryptoTransform transform = aes128.CreateDecryptor();
byte[] result = transform.TransformFinalBlock(p, 16, p.Length - 16);
Debug.Log("If this encrypted stuff was text it would be:"+System.Text.Encoding.UTF8.GetString(result));
return result;
}
public static byte[] StringToByteArray(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
Does anyone know what this might not be working? It must be very close because I am sure it worked at one point. Update: I did a binary compare of when i C# encode\decode and php encode decode. The php encoded Hello World is not the same as the c# Hello world when using the same IV. is this possible or does this indicate they are not using the same configuration somehow.
Upvotes: 1
Views: 795
Reputation: 245
Turns out I had changed the key to have non upper case letters and my GetHexVal function shown there only took upper case letters... Ouch
Upvotes: 1
Reputation: 11348
IDEA: The decryption key has changed.
Very nasty when it happens. Are you using a config file with decryption key? If not What is the decryptionKey used ? Has it changed?
If using localApp.config
or ROOT.config
and the key was changed, you can go hunting around all backups to get the key.
<machineKey decryptionKey="SomeHexValueHere" validationKey="SomeveryLongHexvalueHere" />
But if your PHP version is working, the key must be "known"
Upvotes: 0