Language: C#, Framework: .NET Core 3.1
I am using encryption based on AES.
Research:
Key Format AES
Gilles: An AES key is just a bunch of bits with no structure.
The Key and IV need to be stored since they are randomly generated each time and they are required for Encryption and Decryption.
I need to store it as a string for particular reasons, so I want to be able to convert a byte array to a string and backwards if needed using encoding.
The conversion happens using UTF-8
encoding.
My problem:
I've put a breakpoint in my code and the contents of the byte array are clearly different from the original array. I've tried switching to other encoding formats but this also failed. In a nutshell, the data changed and this would result in being unable to decrypt a message because the AES key and IV would be incorrect.
Update:
The UTF-8
conversion doesn't work when keyBytes
doesn't contain valid utf8 data and the encoder will generate fallback data which causes the problem.
Example:
using (Aes myAes = Aes.Create())
{
bool valid = false;
byte[] keyBytes = myAes.Key;
Encoding utf8WithoutBom = new UTF8Encoding(true);
string key = utf8WithoutBom.GetString(keyBytes);
byte[] outputBytes = utf8WithoutBom.GetBytes(key);
if (myAes.Key.Length == outputBytes.Length) {
for (int i = 0; i < myAes.Key.Length; i++) {
if (outputBytes[i] == keyBytes[i]) {
valid = true;
}
else {
valid = false;
break;
}
}
}
if (valid == true) {
Console.WriteLine("Succes");
}
else {
Console.WriteLine("Error");
throw new Exception("The keys do not match.");
}
}
Result:
- Output: byte[] with a size between 50~54 Error
- Desired Output: byte[32] with the same data as the original array Succes
Question:
Why are the contents of the output byte array different from the original byte array?
The conversion from byte[] -> string -> byte[]
will only work when the initial byte array contains a valid utf8 content. Not every 32 byte array does that.
If the original array contains invalid data, the byte[] -> string conversion will already return some fallback data and a second conversion will convert those fallback values to their corresponding bytes.
If you want to encode an arbitrary byte array into a string, use Base64 or some other general data encoding, but not utf8.