14

I use this code to encrypt a string (basically, this is the example given on the Rijndael class on MSDN):

public static String AESEncrypt(String str2Encrypt, Byte[] encryptionKey, Byte[] IV)
{
    Byte[] encryptedText;

    using (RijndaelManaged rijAlg = new RijndaelManaged())
    {
        // Use the provided key and IV
        rijAlg.Key = encryptionKey;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform
        ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

        // Create the streams used for encryption
        using (MemoryStream msEncrypt = new MemoryStream())
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
            {
                // Write all data to the stream
                swEncrypt.Write(str2Encrypt);
            }

            encryptedText = msEncrypt.ToArray();
        }
    }

    return Encoding.Default.GetString(encryptedText);
}

I use Encoding.Default to convert a byte array to a string but I'm not sure it's a good solution. My goal is to store encrypted text (such as passwords...) in files. Should I continue with Encoding.Default or use Encoding.UTF8Encoding or something else?

Can that have negative consequences on the stored values when I try to encrypt and decrypt them if the files are moved onto different OS'?

John B
  • 20,062
  • 35
  • 120
  • 170
Otiel
  • 18,404
  • 16
  • 78
  • 126

4 Answers4

46

You should absolutely not use an Encoding to convert arbitrary binary data to text. Encoding is for when you've got binary data which genuinely is encoded text - this isn't.

Instead, use Convert.ToBase64String to encode the binary data as text, then decode using Convert.FromBase64String.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks Jon. Saves me from serious bugs. – Otiel Nov 03 '11 at 15:48
  • 9
    See also [Phil Haack's post expanding on this](http://feeds.haacked.com/~r/haacked/~3/5hyXGYRO0Bo/hazards-of-converting-binary-data-to-a-string.aspx) – Ruben Bartelink Jan 30 '12 at 09:28
  • @Jon Skeet,please help me understand your comment "Encoding is for when you've got binary data which genuinely is encoded text".If I have an xml data and i encrypt that into a byte array,is that xml considered as encoded text? – dotnetdev_2009 Sep 20 '17 at 00:19
  • @RennishJoseph: After encryption, it's not encoded text, no - not in the way that `Encoding` deals with. You'd use `Encoding` to convert the XML text into binary data, then you'd encrypt it to get more binary data. Later, you'd decrypt the binary data (with a result that's still binary data), and use `Encoding` to convert the result back to text. – Jon Skeet Sep 20 '17 at 05:19
0

If your goal is to store encrypted information in files, and you have a byte array, you should store it directly - don't convert it to a string at all. For example, in C# you can use File.WriteAllBytes to write a byte array directly to a file. Remember that files hold bytes, not strings (if you write a string into a file, some kind of Encoding will be used to convert it to bytes, even if you are using a technique that doesn't explicitly refer to Encoding).

If you actually need the byte array to be stored as a string (for example, because it will be stored in JSON) then the most common technique is to use base64 with Convert.ToBase64String, as Jon mentioned.

(In non-encryption applications you might have a byte[] that contains a mixture of ASCII and binary data and you want to convert it to a string. In this case base64 works fine but it hides the text - Byte Array In String format is like base64 except that runs of ASCII are preserved - C# version in Loyc.Essentials NuGet package, Java version here)

Qwertie
  • 16,354
  • 20
  • 105
  • 148
0

Yes, Encoding.Default is your machine's current ANSI code page and may well be different between multiple machines/locales. If the data was textual data and to make it portable, you would need to use a fixed encoding format, for example UTF8.

However, as your data is NOT textual data, you can not try and use any textual encoding to convert to a string. The best option is to use a hex or Base64 encoding or keep it as a blob/byte array.

Deanna
  • 23,876
  • 7
  • 71
  • 156
  • This is clearly *not* textual data - it's the result of performing encryption, so it's arbitrary binary data. Any `Encoding` is inappropriate here. – Jon Skeet Nov 03 '11 at 15:00
  • Yeah, clarified a bit once i knew the data wasn't text at all. – Deanna Nov 03 '11 at 15:50
-1

im not 100% sure here but i think that Encoding.Default refers to the system default encoding and yes that can change from system to system..

If i where you i would use UTF8 or some other encoding that does not change from system to system..

for more info about extended ascii look here

http://en.wikipedia.org/wiki/Extended_ASCII

Peter
  • 37,042
  • 39
  • 142
  • 198
  • 1
    No, using UTF-8 is *not* a good solution - this binary data is *not* UTF-8-encoded text; it's arbitrary binary data. – Jon Skeet Nov 03 '11 at 14:59