6

I'm trying to encrypt and decrypt Id with MachineKey.

Here is my code that calls the encrypt and decrypt functions:

 var encryptedId = Encryption.Protect(profileId.ToString(), UserId);
 var decryptedId = Encryption.UnProtect(encryptedId, UserId);

Here is the functions:

public static string Protect(string text, string purpose)
{
    if(string.IsNullOrEmpty(text))
    {
        return string.Empty;
    }

    byte[] stream = Encoding.Unicode.GetBytes(text);
    byte[] encodedValues = MachineKey.Protect(stream, purpose);
    return HttpServerUtility.UrlTokenEncode(encodedValues);
}

public static string UnProtect(string text, string purpose)
{
    if(string.IsNullOrEmpty(text))
    {
        return string.Empty;
    }

    byte[] stream = HttpServerUtility.UrlTokenDecode(text);
    byte[] decodedValues = MachineKey.Unprotect(stream, purpose);
    return Encoding.UTF8.GetString(decodedValues);
}

The input to the Protect method is 15. This results that the encryptedId variable holds the following string: 6wOttbtJoVBV7PxhVWXGz4AQVYcuyHvTyJhAoPu4Okd2aKhhCGbKlK_T4q3GgirotfOZYZXke0pMdgwSmC5vxg2

To encrypt this, I send this string as a parameter to the UnProtect method. The result of the decryption should be 15, but is instead: 1\05\0

I can't understand why. I have tried to use only integers in this function, but I still have the same problem. The output of the decrypt differs.

halfer
  • 19,824
  • 17
  • 99
  • 186
Bryan
  • 3,421
  • 8
  • 37
  • 77
  • That seems to be correct except for the `\0`, no? – Ian Apr 23 '16 at 15:21
  • @Ian: Can I convert that to a int? So I can use It as the digit 15? – Bryan Apr 23 '16 at 15:23
  • Since it is a `string`, I suspect somewhere in the code it interprets (returns) the result as char (probably with UTF-8 format) thus your `1` is represented as `1\0` and `5` as `5\0` (because of the Little Endian). If that is the case, you simply need to replace all `\0` to empty string before returning it. – Ian Apr 23 '16 at 15:25

1 Answers1

7

You have an encoding mismatch, you encode a buffer containing the UTF-16 (Encoding.Unicode) representation of the string (which will interleave \0 as you see given that it uses 2 bytes per character for that string) but you decode it as UTF-8 (Encoding.UTF8). You need to be consistent in both methods.

Alex K.
  • 171,639
  • 30
  • 264
  • 288