1

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 and GetBytes 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.

  • Why is it essential to save it as text/string/ascii? – Ňɏssa Pøngjǣrdenlarp Feb 06 '18 at 18:10
  • AES IV/Key are byte arrays and not strings. I'm not sure why you believe otherwise and how Base64 does not work in your case. Closing as duplicate of the post you've linked. Clearly you are looking for something else and not satisfied with standard approach. You need to [edit] question to clarify your goals. Feel free to edit out all part of the post that discusses treating random bytes as strings and instead explain why Base64 does not work for your case and what exact requirements you have. – Alexei Levenkov Feb 06 '18 at 18:19
  • Also you Base64 sample is very strange - no idea where you found such sample of using `Encoding.ASCII.GetBytes(iv);` for Base64 decoding (https://stackoverflow.com/questions/11743160/how-do-i-encode-and-decode-a-base64-string shows nothing like that) – Alexei Levenkov Feb 06 '18 at 18:23
  • @AlexeiLevenkov I did explain why Base64 didn't work. When using it to convert back and forth it throws an exception when trying to use it as the IV. I supplied the code that throws the exception. I'm not sure how it's a duplicate when I'm telling you I tried doing it that way and it doesn't work. –  Feb 06 '18 at 18:28
  • @AlexeiLevenkov Which is why I cited: https://stackoverflow.com/questions/2295408/how-to-convert-string-to-base64-byte-array-would-this-be-valid –  Feb 06 '18 at 18:30
  • If Base64 encoding is not working it is in your usage, Base64 is the generally way to create an ASCII encoding of binary data—it works. So the real question is why your are having difficulty with Base64. – zaph Feb 06 '18 at 19:46
  • Grabbing some random code written for completely unclear reason as shown in https://stackoverflow.com/questions/2295408/how-to-convert-string-to-base64-byte-array-would-this-be-valid is not real reason. It is very unclear what author of that questions tried to achieve, but it definitely has nothing to do with Base64. Possibly they needed to post Base64 data to some communication channel... – Alexei Levenkov Feb 06 '18 at 23:16
  • @zaph Yeah, it turns out Encoding.ASCII.GetBytes() doesn't work for identical conversions to and from byte arrays from a string. I ended up using Encoding.FromBase64String instead and it works fine. –  Feb 08 '18 at 20:57
  • @AlexeiLevenkov It did not appear to be random code to me as it specifically said use Encoding.ASCII.GetBytes() to convert the base64 string, which is what I was trying to do.. but it turns out that it adds data when converting back to a byte array. The original array being 16 bytes and the conversion being 24. Maybe I misunderstood the point of the question and answer. –  Feb 08 '18 at 21:00

0 Answers0