# Special characters in AES Encryption Key

We all know that AES uses Key, IV and salt. But what if we add special ASCII characters like Alternate 255 (" ") or Alternatively 163 ("£") or Alternate 224 ("α") in the Key or IV or salt.

• Those special character codes are not ASCII or in fact any standard, they are in a codepage used on Microsoft Windows in some countries/locations but not others. – dave_thompson_085 Apr 30 at 2:00

An AES key must be generated completely at random. It's 256 bits, which in practice are encoded as 32 8-bit bytes.

Note that these are bytes, not characters. With a multibyte encoding, the key may have a variable number of characters, and in fact it often cannot be converted to a character string because a random byte string has a large chance of not being a valid UTF-8 encoding.

Since the content of the key is random, you don't get to pick which characters it contains. A key is not like a password which is made of printable characters and meant to be entered by humans. A key is binary data and never meant to be seen by humans.

I don't know if your programming language distinguishes byte strings (binary data) from text strings. If it does, make sure that keys and other cryptographic data (such as the IV for CBC) are always passed around and stored as byte strings.

This applies to all symmetric keys, not just AES keys. Some asymmetric cryptography uses keys that are numbers that must match certain constraints (e.g. being in a certain range, being prime, etc.), rather than arbitrary byte strings. There again, you don't get to pick the numbers, they have to be generated at random within the constraints.

A final note: you mention using AES-CBC. AES is a good choice but CBC is not. It's possible to use CBC securely, but there are also many opportunities to get it wrong. Unless you understand why CBC is ok (which you don't or you wouldn't be asking this question) or you must be compatible with a format that someone else defined, don't use CBC. Instead, use a modern authenticated encryption mode. Popular choices include AES-GCM, AES-CCM and ChaCha20-Poly1305. SIV variants have improved security but they aren't very widespread; use your library's built-in GCM in preference to rolling your own SIV if it comes to that.

• .NET does make a distinction between bytes and characters. On StackOverflow I generally recommend using a PBKDF, because the "key" usually turns out to be a password. – Maarten Bodewes May 1 at 12:40

The key and IV should be completely random bytes with no relevant interpretation as human readable characters.

You can derive a key from a human readable password using a key derivation function.

The IV and salt should just be sampled completely random, such that the entropy is high enough (e.g. 128 bits).

Say the key is 128 bits (=16 bytes) long - each bit should be randomly chosen. If you restrict the bytes to a subset of values, you lessen the number of potential keys, which could make attacks easier. For example if each byte of the key is a random Byte, but restricted to be alphanumeric in ASCII representation, then you have $$2\cdot 26+10$$ possibilities for each byte, which amounts to $$\log_2({(26\cdot2+10)}^{16} ) \approx 95$$ bits of entropy in the key instead of the desired 128.

• An implementation taking 'salt' as input is almost certainly using a KDF, probably a PBKDF, because actual AES does not use salt. – dave_thompson_085 Apr 30 at 2:00
• Okay that means I can add characters like £,¥,€,¢,π,¶,∆,✓,©. Thanks for the information 👍. – Archi2 Apr 30 at 10:40