There are plenty of questions about the difference between AES encryption and hash functions. I read some of them and the general answer is that

  1. AES is reversible as long as the key is exposed.
  2. AES has fixed input size and hash does not.
  3. There is a method to make a hash function based on the block cipher.

I am curious whether there is a difference between AES encryption and hash function with the strong assumptions as below:

A. The key of the AES is never exposed. (Without knowing the key, I believe there is no possibility of decryption and hence one-way function as a hash)

B. For some applications, the input size is always fixed.

In this case, if someone uses AES encryption as the purpose of hash, do any possible problems exist?

4 Answers 4


I am curious whether there is a difference between AES encryption and hash function with the...

Regardless of your assumptions, there is a difference between AES encryption and "hash function." (BTW, which hash function did you have in mind?)

Encryption and hashing are just fundamentally different functionalities.

The key of the AES is never exposed. (Without knowing the key...

How would you use AES as a hash function "without knowing the key"? In order to reproduce the hashes at some later time, you would have to use the same key that was used originally. In order to do that, you would have had to store the key (or "know" the original key some other way).

For some applications, the input size is always fixed...

Why does it matter if the input size is fixed? AES has certain modes of operation (e.g., GCM) that allow it to be used on a wide range of input sizes.

It seems like you should be more worried about the output sizes. The output of a hash function is always the same fixed size (e.g., always 32 bytes for SHA256). But the output of AES (e.g., in GCM mode) will be approximately the same size (a little bigger) than the input.


You can actually make a hash function from a cipher using a construction that I've seen before, although I offer an extension (an "optional patch") to make up for issues that simpler versions have, and I've never seen exactly the patched version. It will even have a fixed output (digest) length. Although the unpatched version also has a maximum input length (or accepts variable input length by giving up fixed output length), the patch addresses this. I really can't ever recommend this approach over anything from the SHA family, especially SHA2 or SHA3 families, but it's possible and as far as I know works well enough.

To be clear, never do this for anything that matters; use established constructions built on primitives meant to be used this way.

The construction:

  • Choose a symmetric cipher. The cipher of choice will determine the maximum input size. For example, if it's AES-128, then you're limited to 128 bits of input.
  • If using a block cipher, choose a mode of operation. In practice everybody I know who did this used DES and ECB, but you could in theory pick AES and use a mode such as CTR or CBC or some such.
  • If using a cipher or mode of operation that requires an IV, either pick a constant IV or make it an input parameter to the hash (as a salt) and optionally specify a default value.
  • Pick a constant string. For a block cipher, it should be a multiple of the block size in length (for AES, that means a multiple of 128 bits), and it will determine the output length of the digest. For a stream cipher or stream-like mode of operation such as CTR, the string length will exactly define the output length but doesn't have to be any specific size.

The use:

  1. Pad the input up to the chosen cipher's key length, using a fixed pattern. In practice people just used null bytes or spaces or something. Optional patch for maximum input length: If the input is longer than the key length, break the input into key-length chunks, padding the last one if needed.
  2. If using a mode that requires an IV and not using a constant IV, generate or pick an IV of the desired size. This will be the "salt", and for password hashing is stored alongside the digest.
  3. Using the padded input (or the first chunk of input, if using the optional patch) as the key and the chosen cipher, mode (if relevant), and IV (if relevant), encrypt the chosen fixed string.
  4. If there are more input chunks, use the next chunk as the key and the chosen cipher, mode (if relevant), and IV (if relevant) to encrypt the output of the last encryption. Repeat this step until there are no more input chunks.
  5. Use the final ciphertext (which is the output of step #3 if there's only one input chunk) as the digest. If you needed an IV (salt), store the IV along with the ciphertext in the same way that salts are stored with password digests.

Written more symbolically:

  1. N = CEIL(InputSize / KeySize). k1, k2, ... kN = CHUNK(Input, KeySize). kN = PAD(kN, KeySize)
  2. If IV desired, IV = RAND(IVSize)
  3. c1 = ENCRYPT(Cipher, k1, IV, ConstantString)
  4. For X = 2..N, cX = ENCRYPT(Cipher, kX, IV, c(X-1))
  5. Return cN

The principle of the security here is that modern ciphers are strong against known-plaintext attacks. That is, even if you know the plaintext (you do, it's a constant value), and even if you know for some ciphertext what the key used to produce it is (easy; you can input your own key for the cipher and derive a ciphertext), you can't determine the key (hash input) for an arbitrary ciphertext (digest).

I have no idea how collision resistant this is. Although symmetric encryption is a 1:1 function of plaintext to ciphertext (or vice-versa) for a given key and IV, that doesn't inherently mean multiple keys can't produce the same ciphertext from the same plaintext. Obviously such a key is weak, and modern ciphers try to avoid having weak keys, but I'm not sure they're totally successful. Throw the feedback function in there for longer inputs and all bets are off; I really don't have any idea at that point.

The most obvious problem with this scheme is that the input length under consideration at any time is limited to the maximum key length. Using the single-round version that doesn't chunk the input and thus has a maximum input length, that is disqualifying for a general-purpose hash function, and even for a password hashing function, you probably want more than the 32 bytes you could get from AES-256. At least one system I know about attempted to solve this using a broken version of the chunked input where each ciphertext was concatenated instead of fed back in as the next input chunk's message; that is dangerously insecure as it means that the pre-image (the input to the hash) can be brute-forced in key-size chunks. That's not a problem for most of the input chunks with AES - even 128 bits is far too much to brute force - but it's a huge problem for the last part of any input slightly longer than a multiple of the key size as, if the input length is known, that trailing part can be brute-forced easily (it's also a problem for all parts of the 56-bit DES keys that the implementation I saw used). You also face the problem that now the output length isn't fixed anymore, and depends on the input length again, but even using the optional patch, you may be opening yourself to a cryptographic attack by segmenting the key this way. Or possibly by repeated use of encrypt with different keys, such as why 3DES with 112 or 168 bits of key material has less security than its key length suggests.

I'm not a cryptanalyst or theoretical cryptographer to tell you whether that, or anything else, are serious problems with this construction - you might want to ask about this on crypto.stackexchange.com - but I would be pretty surprised if it doesn't have some. This falls right into "don't roll your own crypto", even if you're technically using existing primitives.

It also quite likely underperforms SHA2 or SHA3 hashes in software, though with hardware AES support it might be quite fast on modern CPUs. Of course, for passwords, you don't want fast; all modern dedicated password hashing algorithms are deliberately and configurably slow, to mitigate brute forcing of the digests. Non-password things could take advantage of that, though.


Short info: AES

AES is a family of permutations like any block cipher. A block cipher has a short block size like AES has 128-bit. In order to operate you need a mode of operation.

Short info: Hash functions

Hash functions are one-way, deterministic, and in some sense have an unpredictable output (until one calculates). They are mainly built for collision resistance and pre-image resistance (first and second).

A. The key of the AES is never exposed. (Without knowing the key, I believe there is no possibility of decryption and hence one-way function as a hash)

B. For some applications, the input size is always fixed. In this case, if someone uses AES encryption as the purpose of hash, do any possible problems exist?

  • The output size is the first problem. For example; for an integrity check, a good 512-bit hash function is enough. With encryption, there is no integrity without a proper mode of operation and those are not part of encryption like CBC-MAC, HMAC, KMAC, NMAC, GCM, Poly1305, etc.

  • One needs the key to verify, on the other hand, hashing is free. Consider you build a password from a hash function than without the key you can verify the password. With encrypted passwords, one needs the key to verify.

  • You want to sign documents and hashing before signing is part of the security since the first true Rabin-signature scheme. How do you consider reducing the size to 256 or 512-bit to sign the document with encryption?

  • File comparison; one can simply exchange the hash of the files to check the equality; right just 512-bits. Do you want to send the 5GB file encrypted then compared it?

There is a method to make a hash function based on the block cipher.

This is Merkle-Damgard (MD) based construction that uses block cipher on Devies-Mayer method to build a compression function. Unfortunately, there are two major problems for AES to be used in MD

  • AES has related-key attacks that enable building collision if used in MD
  • The block size is 128 and this makes the output of the hash function 128-bit. Not secure enough to find the collisions!

I am curious whether there is a difference between AES encryption and hash function > with the strong assumptions as below:

A. The key of the AES is never exposed. (Without knowing the key, I believe there is > no possibility of decryption and hence one-way function as a hash)

B. For some applications, the input size is always fixed.

if someone uses AES encryption as the purpose of hash, do any possible problems exist?

There are some differences, because in symetric cryptography, block ciphers (which AES belongs to) and Hash functions are not used for the same purpose most of the time, so you will face a different set of problems.

A first assumption would be that hash functions, like block ciphers, from an input makes its output no more meaningful for humans (confidentiality), which seems true, but it is much more complex than that.

Hash functions

Hash functions are designed to be fast. Their goal is to reduce the number of input bits to an arbitrary fixed length (depending on the function). A common-used case is to check the integrity of two packs of data that can be of any representation (eg. A whole Hard Drive, one or multiple files(s), a string in a program or database, arbitrary bits...). Calculating and comparing two hashes is thus faster than comparing the whole data.


Brute forcing: Hash functions are by construction not inversible. But lookup tables do exist to retrieve calculated values, (eg. for passwords, random strings... ). It is possible to check the content of lookup tables online with dedicated websites. They store them as database data. If a hash is not already calculated in the lookup table, it is also possible to bruteforce a hash to retrieve its value.

Collisions: Hash functions can have collisions (two different inputs give the same output). This makes the integrity check ineffective. Cryptographic Hash Functions try to protect themselves against the possibility of forgery (the creation of input data with the same hash as the expected data, a collision) by potentially malicious participants.

Symetric cryptography: AES block cipher

AES is a block cipher that uses 128, 192, 256-bits key lenght with blocks of 128 bits. Block ciphers encrypt a ciphertext from plaintext with a secret key.


An attacker stole the key:

We suppose no problems of key sharing in your scenario. The key is still located somewhere in your system, so the attackers can attack it to retrieve the key. Securely storing cryptographic keys is a hard problem to solve. Even if it is not shared here, since the key has to change after a certain amount of usage.If available, it is better to use dedicated/ software hardware like HSM or keyvaults. Encrypting the key with another key should be done. But it only translates the existing problems to another key.

The key should change:

  • If the previous key is (or suspected) to have been compromised. This could also be caused by someone who had access to the key leaving the organisation.
  • After a specified period of time has elapsed (known as the cryptoperiod). There are many factors that could affect what an appropriate cryptoperiod is. This include the size of the key, the sensitivity of the data, and the threat model of the system.-
  • After the key has been used to encrypt a specific amount of data.This would typically be 2^35 bytes (~34GB) for 64-bit keys and 2^68 bytes (~295 exabytes) for 128-bit block size.
  • If there is a significant change to the security provided by the algorithm (such as a new attack being announced). There are two main approaches for how existing data that was encrypted with the old key(s) should be handled:
    • Decrypting it and re-encrypting it with the new key.
    • Marking each item with the ID of the key that was used to encrypt it, and storing multiple keys to allow the old data to be decrypted.The first option should generally be preferred, as it greatly simplifies both the application code and key management processes; however, it may not always be feasible.

Brute-forcing of the Key:

Trying all possibilities for the 128, 192, 256 bits of the key. This to retreive meningful content from the output. Most of the time, too computably expensive but always works in theory

Exploitable vulnerabilities:

  • Exploitable Mathematical vulnerability in AES. Some do exist, but not all are interesting to exploit from a practical perspective.
  • Vulnerability in the cryptographic library implementation: some common libraries provide AES encryption. They do have exploitable vulnerabilities from time to time. It is much better to use a used, industry standard, updated cryptographic library.
  • Vulnerability in your code implementing the cryptographic library.
  • Vulnerability in the hardware (here CPU) implementing AES specific instructions.


Performing AES can be more computably expensive than a Hash function. It is slower by design, but it may or not be a real problem considering your use case.

Choosing a cipher Mode for AES:

Not all cipher modes provide the same security. Some modes can introduce specific vulnerabilities. In most cases, GCM outperforms the ECB, CBC and PCBC modes.


As we have seen, in your scenario, most problems with AES relate to key management and securisation. Hash function do have other problems but it can be mitigated with the usage of a recent, secured cryptographic hash function recomanded by standards. This is why people tend to prefer to use such cryptographic hash functions over Block ciphers in this kind of use case.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .