I'm attempting to store an IV for AES encryption in a text file.
Based on this post: Storing/Converting the encryption key and IV as strings
I should be converting the byte array to a base64 string.
According to this one: How to convert string to base64 byte array, would this be valid?
I should be using Encoding.ASCII.GetBytes
to do this.
However, when I attempt to set the vector again, using the string saved, it throws an exception telling me it does not match the block size.
Here's the relevant code:
internal static void OutputProviderKeyAndVector()
{
try
{
string s =
Convert.ToBase64String(m_Aes.Key)
+ ":" +
Convert.ToBase64String(m_Aes.IV);
File.WriteAllText(m_FileName, s);
}
catch(Exception e) { Console.WriteLine(e.ToString()); }
}
internal static void InitializeProviderWithKey(string key, string iv)
{
try
{
m_Aes = new AesCryptoServiceProvider();
m_Aes.BlockSize = 128;
m_Aes.KeySize = 256;
m_Aes.IV = Encoding.ASCII.GetBytes(iv);
m_Aes.Key = Encoding.ASCII.GetBytes(key);
m_Aes.Mode = CipherMode.CBC;
m_Aes.Padding = PaddingMode.PKCS7;
}
catch(Exception e) { Console.WriteLine(e.ToString()); }
}
Based on the two posts I mentioned above, I would expect this to work. However, the byte array created for the IV is 16 bytes in length and upon conversion it becomes 24 bytes in length so obviously the conversion is not working.
So, I went a looked for another solution.
I came upon this: How do I get a consistent byte representation of strings in C# without manually specifying an encoding?
In this question the answer with the most up-votes and selected correct supplies two methods that, based on a comment on the answer, are "re-implementations" of Encoding.Unicode.GetString
and Encoding.Unicode.GetBytes
.
So, I gave the unicode conversions a try.
internal static void OutputProviderKeyAndVector()
{
try
{
string s =
Encoding.Unicode.GetString(m_Aes.Key)
+ ":" +
Encoding.Unicode.GetString(m_Aes.IV);
File.WriteAllText(m_FileName, s);
}
catch(Exception e) { Console.WriteLine(e.ToString()); }
}
internal static void InitializeProviderWithKey(string key, string iv)
{
try
{
m_Aes = new AesCryptoServiceProvider();
m_Aes.BlockSize = 128;
m_Aes.KeySize = 256;
m_Aes.IV = Encoding.Unicode.GetBytes(iv);
m_Aes.Key = Encoding.Unicode.GetBytes(key);
m_Aes.Mode = CipherMode.CBC;
m_Aes.Padding = PaddingMode.PKCS7;
}
catch(Exception e) { Console.WriteLine(e.ToString()); }
}
Low and behold, this works, in the sense I can generate the vector byte array and save it as a string which can be used again to encrypt and decrypt.
However, another comment on the answer states that:
GetString
andGetBytes
need to executed on a system with the same endianness to work.
Which leads me to believe, if they're in-fact re-implementations, that the unicode conversion may be subject to this stipulation as well.
So, my question is, is there a better way to convert an AES IV to a string and back? When I say better, I mean at least not subject to the endian stipulation above. At best, perhaps an industry-standard I'm unfamiliar with.