3

My method AESEncrypt(string text) is returning a byte array. If I encrypt a message, and use the returned byte array as an input for AESDecrypt(byte[] text), everything is working fine. The problem is, that I need to convert it to a string and vice versa, so I tried the following:

byte[] encrypted = enc.AESEncrypt("Testmessage");
string encryptedStr = Convert.ToBase64String(encrypted);
byte[] test = Convert.FromBase64String(encryptedStr);

Console.WriteLine((encrypted == test));

I also tried this with Encoding.ASCII.GetString(), Encoding.UTF8.GetString(),

but encrypted == test returns false everytime...

What method do I need to use to convert the AES byte[] to a string and vice versa?

This is the AESEncrypt method:

public byte[] AESEncrypt(string s)
{
    byte[] encrypted;

    using (AesManaged aes = new AesManaged()) {
        ICryptoTransform encryptor = aes.CreateEncryptor(AESKey, AESIV);
        using (MemoryStream ms = new MemoryStream()) {
            using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter sw = new StreamWriter(cs)) {
                    sw.Write(s);
                }
                encrypted = ms.ToArray();
            }
        }
    }

    return encrypted;
}
Nico Schreiner
  • 397
  • 5
  • 13
  • What kind of string? Base64? Hex? I recommend reading [this](https://haacked.com/archive/2012/01/30/hazards-of-converting-binary-data-to-a-string.aspx/) if you want to know why text encoding methods didn't work. In short: they're not built for it. – ProgrammingLlama Nov 28 '18 at 08:58

3 Answers3

4

An encrypted payload held in a byte array is not directly convertible to a string, or at least not without using an ANSI encoding and both sides (encoding and decoding) agreeing on the string's code page. And if you use any Unicode encoding (UTF-8, UTF-16, ...) you're bound to have bytes that contain invalid code points, so who can't be decoded to a character.

That's where base64 comes into play. This is a safe way to represent byte arrays as ASCII strings, a subset implemented by almost every (if not every) encoding. So using that base64 code is fine.

You'll simply want encrypted.SequenceEquals(test), as explained in Comparing two byte arrays in .NET.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
1

The base64 is directly used for this. here is an example:

Encode

public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

Decode

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
    return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
György Gulyás
  • 1,290
  • 11
  • 37
0

Consider byte[] encrypted and byte[] test, when you test for equality with == by default the references are compared not their content. This explains, why you test encrypted == test fails.

You are also asking about how to convert byte[] into a string, which is not related to your encrypted == test test at all. In general you the various System.Text.Encoding.*.GetString(byteArray); preform the conversion but you need to know what encoding was used for the byteArray. This information has to be passed along separately, you might have a specification which says all byte arrays are encoded in UTF-8 or you might pass the encoding along together with the data but there exists no general answer.

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
  • My point is that I want to know if there is a method which allows me to convert a byte array to a string and the string back to the byte array without losing any data. That is the reason why I compare the two arrays. – Nico Schreiner Nov 28 '18 at 09:07