Encryption function gives different output on windows and unix
Asked Answered
D

3

7

I have an encryption tool written in C# that take a string as input. When i run the compiled exe file on my windows machine i get an output that is different from when i run it on the remote UNIX server using mono.

Here is an example:

Windows:

"encrypt.exe 01/01"
Output:
eR4et6LR9P19BfFnhGwPfA==

Unix:

"mono encrypt.exe 01/01"
Output:
Pa8pJCYBN7+U+R705TFq7Q==

I even tried to put the input value in the script and then compile and run it again, and i got the same results.

The decrypt function is located on a remote web service and uses hard coded key and IV values (I'm using those values to encrypt), Decryption output:

Input (String generated on windows):
eR4et6LR9P19BfFnhGwPfA==
Output:
01/01

Input (String generated on Unix):
Pa8pJCYBN7+U+R705TFq7Q==
Output:
????1

This is the encryption function:

string text = args[0];
byte[] clearData = Encoding.Unicode.GetBytes(text);
PasswordDeriveBytes bytes = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
string a = Convert.ToBase64String(Encrypt(clearData, bytes.GetBytes(0x20), bytes.GetBytes(0x10)));
Console.Write(a);

public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
{
    MemoryStream stream = new MemoryStream();
    Rijndael rijndael = Rijndael.Create();
    rijndael.Key = Key;
    rijndael.IV = IV;
    CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
    stream2.Write(clearData, 0, clearData.Length);
    stream2.Close();
    return stream.ToArray();
}

This is the decryption function (i cannot make changes to this):

byte[] cipherData = Convert.FromBase64String(encryptedString);
PasswordDeriveBytes bytes2 = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
byte[] buffer2 = Decrypt(cipherData, bytes2.GetBytes(0x20), bytes2.GetBytes(0x10));
string output = Encoding.Unicode.GetString(buffer2);
Console.Write(output); 

public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)
{
        MemoryStream stream = new MemoryStream();
        Rijndael rijndael = Rijndael.Create();
        rijndael.Key = Key;
        rijndael.IV = IV;
        CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
        stream2.Write(cipherData, 0, cipherData.Length);
        stream2.Close();
        return stream.ToArray();
}
Decillion answered 2/5, 2011 at 23:37 Comment(1)
I see no debug code ensuring that in the encryption function clearData is the same on both platform. Are you sure it is the case? Also I hope you don't use a constant IV outside of your examples...Elastomer
P
1

The problem in this question isn't what you are dealing with, but looking at the difference in results, it appears padding was a concern, so you may want to look at some of the responses in this question, but this answer may help resolve your problem.

http://social.msdn.microsoft.com/forums/en-US/clr/thread/3df8d5aa-ea99-4553-b071-42a2ea406c7f/

You get this problem when the KEY, the IV and the ENCRYPTED DATA are not all of the correct block sizes and 'scheme'. The only way to avoid this problem is to use the IV and KEY generated by the algorithm. You can use GenerateIV to get the algorithm to generate you an IV. Store this away somewhere safe as you will need it. Then simply call the encrypt method and pass in the data. The algorithm will then encrypt the data and set the Key property to the newly generated key. Store this with your encrypted data. That's all there is to it.

Though it is dated, the response that there are various reasons for the difference, but if you can decrypt then the reasons for the difference may be valid is given here: http://lists.ximian.com/pipermail/mono-list/2006-November/033456.html

So, if you can encrypt on one and decrypt on the other (are you able to do this?) then what difference does it make if the results are different?

Pecten answered 2/5, 2011 at 23:49 Comment(4)
I am sending the encrypted data to a web service which decrypts it and saves it in the database. The problem is that I can not change the decrypt function. The key and IV are hard coded in the decrypt function, so I need to use the specified key and IV when encrypting. The problem is the when i decrypt the mono encrypted string i get ???? in front of the string and that is not acceptable.Decillion
@Decillion - Is it possible that argv[0] has some white space? You may want to use String.Trim() on that string to get rid of any extra whitespace.Pecten
Also, when you decrypt, are using base-64 decoding before you decrypt?Pecten
i tried setting the value inside the code text="01/01" instead of text=argv[0], and i still have the same problem. Yes i'm using Convert.FromBase64String(encryptedString), i added the decryption function the web service is usingDecillion
G
0

Perhaps the Issue is that the output is unicode, and the terminal is showing ascii. I commonly see ? in place of misunderstood unicode characters.

Check the Numerical Values of the Byte array, and the quantity.

Ascii is half the quantity of unicode as there are two bytes for each character.

Grundyism answered 3/5, 2011 at 1:17 Comment(1)
Unix decoded string: 98 57 2 57 219 64 199 165 49 0 => ????1 Windows decoded string: 48 0 49 0 47 0 48 0 49 0 => 01/01Decillion
H
0

Have you checked your test string for new lines? A Windows test string would have a carriage-return + line-feeds, while the Unix string would only have line-feed.

Hierolatry answered 3/3, 2013 at 7:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.