Assume I'm using a cryptographic algorithm to pseudo-randomly generate a string that is specified to be 16 characters long. The string will be used as a passphrase when encrypting a file.

So, for instance the string is:

Z±¨Û‹'bó£´µ¼


The hexadecimal equivalent of that string is:

0x5AB1A81CDB8B279D62F3A3B405B51DBC


Is either variant "stronger", cryptographically speaking? In other words, if I use the string as the passphase, or if I convert the hexadecimal numbers into a string and use that as the passphrase, is either one better?

• The title says ASCII, but the example includes several non-ASCII characters. Did you mean ISO-8859-1 instead? – Toby Speight Sep 1 '17 at 8:43

They are both equal.

Passphrase security is based on the amount of entropy that the passphrase contains. In your case, both of your pieces of data are only different in the encoding. The actual entropy that they contain is the same.

You are generating a secret that is (assuming that the random source is really random) 16 bytes long. So it has 128 bits of entropy.

I should note that this answer assumes "cryptographically speaking". However, encoding your passphrase in UTF-8 or ASCII may (in practice) screw up your data. The other answers do a good job at explaining why.

Update: fgrieu correctly notes that this answer assumes that all the entropy in the passphrase is actually used. An example when this is not the case is when you generate a 256 bit key, from which you derive a 128 bit key for 128-bit AES encryption. Here the entropy is reduced to 128 bits.

• The answer would be better with (...) that the passphrase contains (assuming it is all actually used). Problem is, many cryptosystems have only fixed-width or limited-width key, and some implementations ignore data after that, including when the key is intended to be a passphrase. In this case, over-expanding the passphrase will loose entropy. That could occur for BCrypt. On the other hand, some flawed implementations of BCrypt are known to silently replace non US-ASCII characters with ? Here, base4 encoding might save the day. – fgrieu Sep 3 '17 at 13:17

That's actually a hard to answer question, but not for cryptographical reasons, but because of how unicode works (and what you mean by '16 unicode characters')

For one, by unicode, I assume you mean UTF-8 (it's obvious that 16 UTF-16 characters can hold far more possible passphrases than 32 hex characters).

Now, on one hand, not all 32 hex character strings correspond to a valid UTF-8 passphrase; for example, no UTF-8 character starts off with an initial byte 0xff.

On the other hand, some UTF-8 characters can be as long a 4 bytes; if you have 16 of these characters, that's a total of $2^{336}$ possibilities there, far more than can fit in 32 hex digits.

So, by '16 unicode characters', what do you mean? Do you mean as many characters as can fit in 16 bytes? Or, do you mean 16 UTF-8 characters (including those that can be multibyte)?

• @MaxVernon: can your 'single byte character' represent all 256 possibilities, including 0x00 and 0xff? – poncho Aug 31 '17 at 18:41
• good point. Not in a string, I suppose. But as the hexadecimal representation, then certainly... I think that actually answers the question quite nicely. – Max Vernon Aug 31 '17 at 18:43
• There are unicode characters that in UTF-8 more than 4 bytes, 🇯🇪 is F0 9F 87 AF F0 9F 87 AA and it gets even wielder with composites: 👨‍👩‍👦‍👦 is F0 9F 91 A8 E2 80 8D F0 9F 91 A9 E2 80 8D F0 9F 91 A6 E2 80 8D F0 9F 91 A6. 🤣 – zaph Aug 31 '17 at 19:31
• The equivalence given in the question implies ISO-8859 (part 1 or part 15), not UTF-8. – Toby Speight Sep 1 '17 at 8:38
• @zaph As i understand, 🇯🇪 are 2 Characters and 👨‍👩‍👦‍👦 are 7? – 12431234123412341234123 Sep 1 '17 at 10:55

Strictly cryptographically speaking, both will represent the same entropy… just differently encoded. So, the strength can be assumed to be equal.

The main difference between binary and hex will practically be that the hex representation is easier/safer to handle programmatically since it avoids potential confusion caused by handling the binary string in unicode environments (poncho's confusion in his answer hints at that fact) and/or when exchanging the data via non-binary channels.