3

I have a requirement to create a byte[] with length 16. (A byte array that has 128 bit to be used as Key in AES encryption).

Following is a valid string

"AAECAwQFBgcICQoLDA0ODw=="

What is the algorithm that determines whether a string will be 128 bit? Or is trial and error the only way to create such 128 bit strings?

CODE

    static void Main(string[] args)
    {
        string firstString = "AAECAwQFBgcICQoLDA0ODw=="; //String Length = 24
        string secondString = "ABCDEFGHIJKLMNOPQRSTUVWX"; //String Length = 24
        int test = secondString.Length;

        byte[] firstByteArray = Convert.FromBase64String((firstString));
        byte[] secondByteArray = Convert.FromBase64String((secondString));

        int firstLength = firstByteArray.Length;
        int secondLength = secondByteArray.Length;


        Console.WriteLine("First Length: " + firstLength.ToString());
        Console.WriteLine("Second Length: " + secondLength.ToString());

        Console.ReadLine();
    }

Findings:

For 256 bit, we need 256/6 = 42.66 chars. That is rounded to 43 char. [To make it divisible by 4 add =]

For 512 bit, we need 512/6 = 85.33 chars. That is rounded to 86 char. [To make it divisible by 4 add ==]

For 128 bit, we need 128/6 = 21.33 chars. That is rounded to 22 char. [To make it divisible by 4 add ==]

Artemix
  • 2,113
  • 2
  • 23
  • 34
LCJ
  • 22,196
  • 67
  • 260
  • 418
  • 1
    If you can use GPL code (i.e. you publish under GPL), you might want to look at the KeePass source code (www.keepass.info) which has lots of Utility classes and stuff to deal with keys. – Philipp Feb 19 '13 at 09:43

3 Answers3

6

A base64 string for 16 bytes will always be 24 characters and have == at the end, as padding.

(At least when it's decodable using the .NET method. The padding is not always inlcuded in all uses of base64 strings, but the .NET implementation requires it.)

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Thanks, making the last two chars as '==' does the trick. What will be the logic for a 32 length byte[] ? – LCJ Feb 19 '13 at 09:58
  • 2
    A byte uses 4/3 characters, so x number of bytes uses `(x*4+2)/3` data characters. For 32 bytes that is 43 characters, and then it has a single `=` to pad it to an even four-character boundary. – Guffa Feb 19 '13 at 10:35
3

In Base64 encoding '=' is a special symbol that is added to end of the Base64 string to indicate that there is no data for these chars in original value.

Each char is equal to 6 original bits of data, so to produce 8 bit values the string length has to be dividable by 4 without remainder. (6 bits * 4 = 8 bits * 3). When the resulting BASE64 string is shorter than 4n then '=' are added at the end to make it valid.

Update

Last char before '==' encodes only 2 bits of information, so by replacing it with all possible Base64 chars will give you only 4 different keys out of 64 possible combinations. In other words, by generating strings in format "bbbbbbbbbbbbbbbbbbbbbb==" (where 'b' is valid Base64 character) you'll get 15 duplicate keys per each unique key.

Artemix
  • 2,113
  • 2
  • 23
  • 34
  • When there are 22 chars and '==', it works as suggested by @Guffa. Then it should be 22*6 = 132 bit, isn't it? How is it becoming 128 bit? – LCJ Feb 19 '13 at 09:57
  • 1
    @Lijo Base64 is used to encode bytes. So 132/8 = 16.5 bytes which is effectively 16 bytes. 16 * 8 - 128 bits of data and 0.5 * 8 = 4 'zero' bits reqired for alignment. In other words only 2 bits of last char are used for storing data and 4 remaining bits are there because you cannot have 2 bit char. – Artemix Feb 19 '13 at 10:41
  • For 256 bit, we meed 256/6 = 42.66 chars.. That is 43 char... [And to make it divisible by 4 add one `=`.] Isn't it? – LCJ Feb 19 '13 at 11:05
  • 1
    @Lijo Yes, you are correct. Note, however, that last char before '=' should meet certain criteria in order to avoid generating duplicate keys. – Artemix Feb 19 '13 at 11:15
  • Can you please provide some reference to that (duplicate keys)? – LCJ Feb 21 '13 at 17:05
  • 1
    I think you need to use only those characters that encode higher 2 bits. For reference see this post: http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c – Artemix Feb 22 '13 at 07:48
  • 1
    Looks like you need only these characters: wgQA (48, 32, 16 and 0). Wikipedia has a [good article](http://en.wikipedia.org/wiki/Base64) on the subject. – Artemix Feb 22 '13 at 07:56
0

You can use PadRight() to pad the string to the end of it with a char that you will later remove once decrypted.

dutzu
  • 3,883
  • 13
  • 19
  • @Lijo To check if a string is 128 bit you just check if the length is 16 (one char == 8 bit therefore 16x8 = 128 bits) – dutzu Feb 19 '13 at 09:44