# About the AES algorithm key and ciphertext

I have the two following questions about the AES algorithm:

A- Does the key need to follow any specific pattern apart from length or can it be a completely random string? So, if I select 16 random ASCII characters, could I use them directly as a 128 bit key? If answer is NO, are there encryption algorithms in which this could be done? If answer is YES, would I receive any valid output in question B?

B- If I use a random key to decrypt a specific ciphertext, would I receive any valid output (different from the original plaintext obviously)?

• If the key needs to follow a pattern, that reduces the number of keys possible, which reduces the security of the cipher, so no. What's a valid output? Jan 24, 2016 at 1:50
• ASCII is only 7 bits. 16*7=112 bits, not 128. Jan 24, 2016 at 1:57

A) AES keys are comprised of binary bits, not strings of characters. They should indeed be random, and no other properties are required. However, this does imply that they should be random bits, and not ASCII characters.

B) If you decrypt ciphertext with an arbitrary random key, you will get some bytes as the plaintext. Whether these bytes constitute a valid plaintext depends on your specific definition of valid, but for most definitions of valid, the answer is no. If, however, you are really asking if it will cause the decryption to fail, then that answer is also no.

A: Any encryption key for any symmetric algorithm can and should be a random string of bits. Applying any kind of pattern would reduce the keyspace and thus reduce security.

A string of 16 random ASCII characters would work as a key, but it would not be a very good one. A random bit string of that length has 128 bits of entropy. There are 95 printable ASCII characters, giving 6.57 bits of entropy per character and a total of 105.12 bits of entropy for the string. This is fairly secure, but not as good as it could be.

What is usually done in practice is to use a memorable, long passphrase and to run it through an S2K (string-to-key) function, one that is designed to be inherently slow. The passphrase is hashed, then the result is hashed again, and this is repeated thousands or millions of times. Salt is also commonly used to make the same passphrase result in different keys. Both of these measures make life difficult for an attacker trying to find the passphrase by brute-force search; the slow hashing slows down the trials, and the salt prevents the use of rainbow tables.

Section 3.7 of RFC 4880 lays out three S2K schemata used in the OpenPGP protocol. The good one uses salt and a user-specified iteration count that can range from 1,024 to over 65 million.

B: Well, yes, if by “valid” you mean “the function has an output”. You would get a random-looking string of bits of the same length as the original message. Note that OpenPGP, for example, uses a 16-bit value to detect an incorrect key immediately, before wasting a lot of time using it to incorrectly “decrypt” a long message. But if you don’t check, then yes, it will spit out something.

A 128-bit key for AES need only be 128 bits long. No other properties are required, though other properties might be desired.

If you choose a 16-character string, then you're not really using those 128 bits to their fullest. ASCII only supports 7 bits per character (the first bit of each byte is always zero), and your real-world entropy top out at around 6 bits per character of ASCII text. So a 16-character password if used directly for 128-bit AES has the same level of security as a 96-bit key, rather than 128-bit key.

For an encryption key, you want to use those precious bits to their fullest; you want each bit to be equally unguessable.

The best way to do that is to use a hash. The cool thing about using a hash is your password doesn't have to be exactly 16 characters; it can be shorter or it can be longer, and you will still get a consistently random distribution of bits in your resulting key.

MD5 will produce a 128-bit output, so that's convenient. But really, MD5 is pretty broken and your hash output doesn't need to be exactly the same size as your key, it just has to be at least as big as your key. You could just as well use SHA-256 and then just take the first 128 bits of hash output for your key. Or the last 128 bits. Or the middle 128 bits. As long as you're consistent, it doesn't matter.

Which, as long as it doesn't matter, how about we run the hash several times. That way an attacker will have to run the hash several times for each guess if he wants to guess our password.

Actually, someone's already thought of this, and there is a list of "Key Derivation Functions" specifically designed to take an arbitrary input of any type and size and produce a key at least X bits long, often with the added property that deriving the key from the password takes a LONG time (and perhaps a LOT of memory).

These have been discussed pretty extensively here, so just search for PBKDF2 or scrypt for more details.

So to summarize, the answer is yes it works, but no you shouldn't do it because there are better options ready-made that make your keys better in every way.

• SHA-1 has a 160 bit output hash, not 128 bits. I think the only hash algorithm that is both reasonably common and has a 128 bit output hash is MD5, which I would be wary of using even in a PBKDF these days. SHA-1 is OK (the currently discussed attacks on it are irrelevant for KDFs) and SHA-2 should be even better (as in "two times infinity is infinity" better).
– user
Jan 24, 2016 at 12:34
• Oops, you're right, got the numbers backwards. Jan 24, 2016 at 15:35
• So, using KeyGenerator(e.g. java) is a better choice? Jun 27, 2023 at 0:26
• @NickDong I don't know the details of Java's `KeyGenerator` (like, I have no idea how it actually works or what it does), but just about anything would be better than using simple human input directly as a symmetric cipher key. If `KeyGenerator` is made for this purpose then it probably does the right thing, but if you're gonna use it I'd make a point of finding out what it's doing, so that if you decide to change languages you don't lose the ability to decrypt your stuff. Jun 30, 2023 at 16:37

As far as I know its not the string working as a pattern or key, but array of bytes for example. Key length is very important. You do not use a random String key as keyword, but you can generate 128bit array of bytes from a string keyword. Hash algorithms does that for you. As an example you can use SHA hash algorithm to hash a keyword,Then use 128bits of it as key.

See my codes as an example here. Its on unrelated subject but I think it has all you need in it, and its coded with Java.

About your second question, I'm afraid you will not get a valid output. If you successfully decrypt data with wrong key, you will only get wrong meaningless bytes as a plain text.