So I am trying to recover from a server disaster that wiped out my code (yes, yes, I know, backup strategies etc etc. The IT department’s backups all magically were unrecoverable and the RAID6 setup apparently suffered 3 HDD failures in the span of a couple of hours…)
The C# block that does the encryption is as follows:
private string EncryptStupidThing(string thing)
{
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] encodedSecret = encoding.GetBytes(thing);
byte[] encodedKey = encoding.GetBytes("<a key that is 16 characters long>");
Aes rijndael = Aes.Create();
// the encodedKey must be a valid length so we pad it until it is (it checks // number of bits)
while (encodedKey.Length * 8 < rijndael.KeySize)
{
byte[] tmp = new byte[encodedKey.Length + 1];
encodedKey.CopyTo(tmp, 0);
tmp[tmp.Length - 1] = (byte)'\0';
encodedKey = tmp;
}
rijndael.Key = encodedKey;
rijndael.Mode = CipherMode.ECB;
rijndael.Padding = PaddingMode.Zeros;
ICryptoTransform ict = rijndael.CreateEncryptor();
byte[] result = ict.TransformFinalBlock(encodedSecret, 0, encodedSecret.Length);
// convert the encodedSecret to a Base64 string to return
return Convert.ToBase64String(result);
}
Now I need to catch this base64 string in PHP (it’s being sent via $_GET['task']) and decrypt it.
I know this works somehow; I had it working before.
I’ve tried combinations of sending the ciphertext or the raw $_GET[‘task’] in, with or without the various options; At best, I get gibberish out; most times I get Wrong final block length out.
Am I missing something obvious? I made this work before, so I know there must be some way to do it, but my brain is unable to recollect/reconstruct the code…
It’s… possible i suppose, but a 16 character key should be 128 bits long… so there shouldnt be any padding there… unless the key is somehow not 128, but i would have thought that would be overt…
Well i dont have control over the C# code; but from the code block, it would seem they’re null-padding it (byte value 0), you cant… really copy a key containing nonprinting characters…especially null, which terminates strings in most output commands…
that’s why I said you should copy a string (for example bas64 encode it) but if you do not have the possibility to access the c# part it does not help at all
In vaguely scrabbling around trying to find something that would work, I seem to have run over another weird one:
If I HMAC SHA512 something in C#:
Encoding encoding = Encoding.UTF8;
using (HMACSHA512 hmac = new HMACSHA512(encoding.GetBytes("<a very long string that makes up 128 characters in total>")))
{
var message = encoding.GetBytes(thing);
var hash = hmac.ComputeHash(message);
return Convert.ToBase64String(hash).TrimEnd(padding).Replace('+', '-').Replace('/', '_');
}
(the bit at the end is to handle URL encoding)
and then shove it through PHP: $check = hash_hmac("sha512", $nonb64 , <the same very long key>, true);
I get different hashes.
The key is hex-identical.
The message is hex-identical.
How am i getting different hash values?
The hash starts identically, but then wanders off… and comes up with a different length??
C# says: 5caef81a38714cbce93ab36b6fe3f138fd7a6ae6f6ba410f43827d9b2dd2f72330b3a551073f03cf467c911c1b2b008038695c43aba8a35ca4e88a58b959ac
PHP says: 5caef81a38714cbce93ab36b6fe3f138fd7a6ae6f6ba410f43827d9b2dd2f72330b3a551073f03cf467c911c1b2b00bf00e1a5710eaea28d7293a22962e566b3
EDIT: and the next time i run it, it wanders off even earlier: 13382a972677086246f367c64439b62d22eb1442e32497648a4f8b6e8424856d24efe267de0bf4b189cc5d9199c7293332555aefac0b3145cd5cd8c32814 133fe0aa5c99dc21891bcd9f1910e6d8b48baff1442e3249764fe293e2dba109215b493bf899f782fd2c627317646671ca4ccc9556bbeb02cc5173573630ca05