9

Are there any security implications of converting a byte-array encryption key into a Base64 string before use?

I am creating a generic encryption helper for a project, and for the sake of consistency and generality, I use byte arrays for all inputs and outputs (plain data, key, salt, etc)

However, the encryption library I use internally expects strings. I am worried that encoding the key as a base64 string before use might somehow weaken it's strength in terms of entropy, etc.

Any thoughts? In general, does Base64 encoding affect encryption strength in any way?

prmph
  • 227
  • 1
  • 2
  • 5

3 Answers3

2

As long as the key is converted back into the binary format before use, the bit-dilution caused by the base-64 encoding will be undone.

However, if you're passing keys around an application be careful of how you do it. Wipe text buffers, minimize transits between methods and applications, etc.

kronenpj
  • 216
  • 1
  • 2
  • Thanks for the reply. I don't have access to the source of the encryption library, but I assume there is no conversion back to a byte array; the library expects a string key, and cannot assume the caller is passing a base64 encoded string. In any case, my question is focused on what happens when the encoded key is used as-is. You alluded to bit-dilution, could you explain more? – prmph Oct 18 '14 at 23:32
  • Base-64 encoding involves converting an 8-bit clean stream into a 7-bit (or less) stream. This snippet from wikipedia explains it better: [http://en.wikipedia.org/wiki/Base64] 'The number of output bytes per input byte is 4/3 (33% overhead), up to rounding. Specifically, given an input of n bytes, the output will be 4 \lceil n/3 \rceil bytes long, including padding characters.' This causes fewer bits to be used as the key, assuming a fixed key length in bits. – kronenpj Oct 18 '14 at 23:37
  • So, if the library uses the string directly as the key, or you suspect it does, try to use a more compact encoding than Base-64 to encode the string. Also, depending on the language, it may allow something more akin to 8-bit binary than you realize - like UTF-8. – kronenpj Oct 18 '14 at 23:48
2

There is no way that a modern encryption library operates on characters. All modern ciphers are defined to operate on bytes (some are defined to operate on bits, but most libraries will assume a byte is the minimum unit of data). If your library accepts character strings then they will be converted to bytes within. Note that e.g. std:string does not have to contain character strings, it can contain byte strings (a.k.a. octet strings) as well.

On the other hand most encryption libraries use the full range of the key space. This means that the bytes that make up the key can have any value. So as long as your base 64 encoded key has a valid key size it may be accepted. In that case the only problem is that base64 will contain 3/4th of the entropy of a fully random key. So if you have a 192 bit AES key it will be converted to an AES 256 bit key. In that case you should not claim 256 bit security, as the amount of possible keys in your scheme is still 2^192.

If the encryption library itself decodes the base64 then your key is first converted 1:1 to base64 and then back to the original key again. Obviously in such a case base64 does not make a difference. You would expect that conversion from base64 or hexadecimals is well documented for the library.


There seems to be precious little information available for Synercoding.Encryption - that's not a good sign.

If the key is not a key but a password fed into PBKDF2 then you just need to provide it enough entropy. If that is directly fed into PBKDF2 or if it is first encoded as base64 makes no difference.

Funny enough for a password based function PBKDF2 is also defined to operate on bytes. The API should therefore also specify the character encoding. Usually it is compatible with ASCII though, so base 64 is likely to work. It can even be used as some kind of compatibility layer between implementations of PBKDF2.

Maarten Bodewes
  • 4,562
  • 15
  • 29
2

Since all decent cryptographic algorithms are defined to operate on sequences of bits or bytes, there are only two possibilities for your "encryption library":

  • either it internally converts character strings back to bytes;
  • or it uses some custom algorithm based on characters.

In the first case, the library has a sloppy API; it should not be artificially limited to character strings. In the second case, this is worse: custom, homemade algorithms are invariably weak.

In any case, the most important thing is not the library but the algorithm. The library is responsible for implementing the algorithm correctly, but the security comes from the underlying algorithm and how it is used (assembly of cryptographic algorithms is often called a protocol). If what your library does is only known as "it does some encryption" then there is no way to give any significant answer to your question. If your library does not specify what protocol it implements, as a well-defined and studied standard, then the only sane action you may perform is to get rid of that library, and go find a better one.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Very informative comments. Actually, the library is called [Synercoding](); it is one of the most popular encryption libraries for Winrt available on nuget.com. – prmph Oct 19 '14 at 04:37
  • Very informative comments. Actually, the library is called [Synercoding](https://www.nuget.org/packages/Synercoding.Encryption/), one of the more popular encryption libraries for Winrt on Nuget. I use it's symmetrical AES encryption method, and the code is posted on a [StackOverflow question](http://stackoverflow.com/questions/14457765/encryption-engine). A string password is passed to the Rfc2898DeriveBytes function (PKBDF2) in .NET, to derive the key. So the actual key used is a byte array, but it is derived from a string. So my question is about the effect of encoding this initial password. – prmph Oct 19 '14 at 04:52
  • @prmph so your question really is about "is it ok to feed in a base64 string in to PKBDF2" – Scott Chamberlain Oct 19 '14 at 06:08
  • 2
    @prmph: In that case, using Base64-encoding on your source key to turn it into a string _should not_ introduce any additional weakness: PBKDF2 can work on arbitrarily long inputs and you will not lose key entropy that way. Of course, I certainly don't vouch for the quality of that library (popularity has never implied quality, in software or in anything else). – Thomas Pornin Oct 19 '14 at 12:23
  • Ok, this comment gives me the information I'm looking for; which I could mark as an additional answer. +1 for "popularity has never implied quality, in software or in anything else – prmph Oct 19 '14 at 21:21