byte *key;

String skey = "abcde"

If I convert skey to bytes and uses it to encrypt AES 128 bit, 192, and 256 bits. How AES would work with small key sizes or large key sizes? Is it key expansion or key round that would make it work or it would break? What actually happens behind?


1 Answer 1


TL;DR: it depends on the API implementation of the AES encryption function you are using.

AES is a block cipher with specific key sizes, 128, 192, 256 bits. To use it as an actual encryption mechanism it is required to use it in a specific mode of operation. Otherwise it is only useful to permute a single 128 bit block. These mode of operations (usually) do not affect the key size.

You can broadly distinguish the following possibilities:

  1. If you use a programming API with a badly sized key then it usually will generate an error (special return value or exception);
  2. Some API's actually implement the full Rijndael instead of AES; AES is a subset of Rijndael. Rijndael accepts all key sizes between 128 and 256 bits with a step of 32 bits (AES is based on 32 bit operations) but it will not accept just any key size such as a key size smaller than 128 bits as in your example;
  3. Yet other API's do not perform input validation at all, for instance the horribly crappy C/PHP mcrypt library simply right-pads with zero bytes and may even use a partial key if it is too big (nowadays it additionally outputs a message to the warning log);
  4. If you're using a lower level programming language and API (your code kind of hints at C) then it may be that you first need to select AES-128, -192 or -256 and then provide a key. As the key size is now known this could be simply a pointer in memory. In that case the short key will be used together with any byte value that comes after the key. If you would not be able to re-generate (guess, brute force or simply get lucky because the program always behaves similarly) then the message you've just encrypted may get lost forever (!). If the key is too large then part of the key may be simply ignored (just like it would for possibility #3).
  5. Sometimes API's are also programmed on a higher level where instead of a key a password is accepted. This should be apparent from the API, if the API was designed well. In that case a Password Based Key Derivation Function (PBKDF) should be used to convert a password to a 128, 192 or 256 bit key. This function should be documented as well. The result is called Password Based Encryption or PBE. One standard for this is PKCS#5: Password-Based Cryptography Specification (Version 2.1) in RFC 8018.

Note that the bits in an AES key should be indistinguishable from random. A string such as a password doesn't have this property, even if it is encoded to bytes. ASCII for instance only uses 95 printable characters per byte. Even though other encodings (Windows-1252 or UTF-8) may contain more possible values per byte, they won't match the requirement of having 256 random values per byte.

PBKDF's (see reason #5) such as PBKDF2, bcrypt, scrypt or Argon2 strengthen the password and output the requested number of bytes, all of which depend on the password. The output of the PBKDF can then be used as key (and other pseudo random data such as the IV).

  • $\begingroup$ I tried this example and library written in C, I tried 32 size string key(converted to byte), 64, 128 and all worked, by work I mean encryption and decryption was smooth.github.com/spaniakos/AES/blob/master/examples/aes/aes.pde $\endgroup$ Commented Nov 30, 2017 at 10:29
  • 1
    $\begingroup$ Encryption hasn't succeeded if the application runs, encryption succeeds if the result is secure. This is the main difference with most other functionality that is programmed. With that API you have to provide the number of bits I see. So if you enter 256 bits (the max) and use a 64 byte / 512 bit key then it is likely that the last part of the key is simply ignored. Try to vary the last byte for encryption / decryption. It will likely succeed even though the key is different. $\endgroup$
    – Maarten Bodewes
    Commented Nov 30, 2017 at 10:38
  • 2
    $\begingroup$ @newbeedeveloper that's the difference between a key and a password. What you are trying to do is fitting a password (string of arbitrary length) to an AES key (which is fixed size by its protocol). As Maarten already mentioned it's not always a good idea. You may have a look on Password-Based Key Derivation Function which are functions specifically designed to get key of required size from passwords $\endgroup$
    – gusto2
    Commented Nov 30, 2017 at 11:28
  • $\begingroup$ does 4 really occur? what about the strlen? $\endgroup$
    – kelalaka
    Commented Nov 15, 2020 at 20:20
  • $\begingroup$ Oh, absolutely. For instance OpenSSL does not have a specific key size parameter (and even if it did, it could be set incorrectly). Lower level libraries also often don't contain any check on this. In that case uninitialized memory may be included, and that may contain any value. That's what you get with pointer arithmetic / no memory protection. Of course, you'd hope this will be caught during testing, but if it is always initialized to the same value during testing then it might pop up on a different runtime / optimization level / whatnot. $\endgroup$
    – Maarten Bodewes
    Commented Nov 15, 2020 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.