6
$\begingroup$

Is it safe to use the SHA256 of a hard-to-bruteforce string as the key to encrypt data with AES256?

$\endgroup$
  • $\begingroup$ you could obviously just hash every brute-force key $\endgroup$ – super Feb 11 at 18:12
1
$\begingroup$

The definition of hard-to-bruteforce string is vague since it is not clear under which conditions, when, and against who. Therefore, while assuming that you have a hard-to-bruteforce string as a password we need to turn the usual advice.

We assume that the attacker knows the key generation method, too. Therefore, firstly, the attacker will try to brute-force for possible strings and simple or complex combinations.

The users should choose passwords from entropy sources for this kind of method. The usual advice is using diceware generated passphrases that will provide high entropy passwords.

If the user has a high entropy password to enter any Cryptographically secure hash function, i.e. it has pre-image, secondary pre-image, and collision resistance, then the user can be safe., note that there is no iteration, no prevention against parallelization, though this is not necessary if you have a password with high entropy. For passwords, collision resistance is not important, pre-image, secondary pre-image resistance are important.

For multiple key derivations, you can use Hashed Message Authentication Code (HMAC)-based key derivation function (HKDF). HKDF with the expand can increase the entropy of the Input Key Material (IKM). If the entropy is good, then you can use the extract mechanism.

For key generation from passwords, you can also prefer, passwords based key generation algorithms. Bcrypt (1999), PBKDF2 (2000) and Scrypt (2009) are well-known examples. There is also new Argon2 which has the winner of the Password Hashing Competition in July 2015. Argond2id is recommendable. One of the aims of Password-Based Key Derivation functions is reducing the timing of the Brute-force password searching - like hashcat. This is achieved by iterating the hashing many times, like 10K, using large memory to reduce parallelization as done in GPU's.

Keep in mind that, in general, humans cannot remember hard-to-bruteforce string. It is advised to use a password manager to keep passwords. Now, it turns into the chicken-egg problem. How to remember the hard-to-bruteforce string for the password manager.

The Password-Based Key Derivation Functions are the solution for general users. With some restrictions on the passwords ( forcing some level of password space, 10-char, 1 upper, 1 decimal, 1 punctuation, etc...) the attack time can be adjusted according to current known attack levels. So, in practice, the minimal security is set. It is better to teach them the diceware.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Hupersons meaning? $\endgroup$ – forest Aug 20 '19 at 7:33
  • $\begingroup$ @forest just a joke. Hu-man -> to Hu-person. I'll update the answer... $\endgroup$ – kelalaka Aug 20 '19 at 7:35
  • $\begingroup$ It answers my question. What i mean behind 'hard-to-bruteforce string' is that we don't bother about the complexity of the string for my question. I just wanted to know if it was a safe way to use SHA256 to generate a key for AES256 regardless the string used for the hash. $\endgroup$ – xaoc2nd Aug 20 '19 at 13:13
  • $\begingroup$ PBKDF2 is a well-known example of not recommendable Password-Based Key Derivation Function. Problem is, it uses so little memory that it is ideal for ASICs/FPGA/GPU-based attacks, which abound. While Bcrypt is far from ideal, it is already better. There is now few reasons to use anything less than scrypt, Argon2, or Balloon. $\endgroup$ – fgrieu Feb 10 at 12:57
  • $\begingroup$ @fgrieu you are right, updated a bit. I need to read the Balloon, then edit. Thanks. $\endgroup$ – kelalaka Feb 10 at 13:33
3
$\begingroup$

Yes, it is safe. The answer of @kelalaka (the first part, before update) it not correct.

The OP is saying that the password is a strong string which is hard to bruteforce. That's why the answer of @kelalaka the attacker, firstly, will try to brute-force is not relevant to the question. Everything @kelalaka is saying about password stretching is correct, but it is not relevant to this particular question.

I am curious why would you want to use SHA256 instead of password, if your password is complex and is hard to bruteforce. But this is another story.

I would suppose that some readers who didn't read the question attentively will vote my answer down. Some people don't think much and just apply patterns that they have in their minds, like Password? --> hashing is bad --> use stretching instead But guys, read the question once again.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ I didn't know you could use a password, I thought you had to use a string of 256 bit to use AES 256 $\endgroup$ – xaoc2nd Aug 20 '19 at 7:38
  • $\begingroup$ I've updated my answer, according to this, you may need to update. $\endgroup$ – kelalaka Aug 20 '19 at 9:47
  • $\begingroup$ "I am curious why would you want to user SHA256 instead of password, if your password is complex and is hard to bruteforce. But this is another story.". Why is that unclear, it's a basic entropy extraction, right? That it is hard to brute force doesn't mean that it is condensed into 256 bits after all? $\endgroup$ – Maarten Bodewes Feb 10 at 15:37
0
$\begingroup$

If you have a string with enough strength to be considered a secret then the action that you want to perform is to extract that entropy into a 256 bit key. For this we generally have to assume that the strength is 256 bits, or the actual strength of the resulting 256 bit key will be smaller than 2^256. Generally passwords have a strength of max 40-80 bits or so, so a normal password would definitely not suffice. For normal passwords you'd use a PBKDF.

To implement such a strategy we use a KDF, a key derivation function. If you have a sufficiently strong input then a Key Based KDF or KBKDF will do. We have one extra requirement for this KDF and that is that it is able to accept any sized input for the keying material, and not just a key. This is basically the extraction requirement mentioned before. The KDF should not only operate on actual keys as input key material.

There is one KDF that explicitly decouples the extraction from deriving the keys called HKDF, which consists of HKDF-Extract and HKDF-Expand. As the name implies, HKDF relies on HMAC, which in turn relies on a hash. It doesn't require any other primitives, so you can implement it using just a hash function such as SHA-256 (not for the uninitiated, mind you). If you just need one reasonably sized key, you can use just HKDF-Expand.

That said, just using SHA-256 as poor-mans-KDF is probably fine. It should nicely perform the extraction for you and give you relatively well distributed output after all.


One important factor is that all these KDF's operate on binary data. However, you start off with a string. So you first need to convert this string to bytes. That means choosing a character encoding such as US-ASCII or it's compatible Unicode version UTF-8. Of course, it is then of vital importance that:

  1. you specify this character encoding and
  2. that you enforce that input doesn't fall outside the range.

If you don't you may get keys that don't match and that's never nice (if not outright fatal for a project).

|improve this answer|||||
$\endgroup$
-1
$\begingroup$

As kelalaka suggested, a single SHA256 hash of the password is not sufficiently secure, although it works. PBKDF2 uses many chained iterations of a hash like SHA256 to derive an AES key from a password. bcrypt, scrypt, and argon2 are newer key derivation functions that increase the difficulty of deriving the key by implementing an iterative hash that also requires a lot of memory (which GPUs typically do not have).

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ Unfortunately you didn't read the question properly. The OP says that the password is a strong string which is hard to bruteforce. SHA256 will not do it weaker. $\endgroup$ – mentallurg Aug 19 '19 at 22:58
  • 1
    $\begingroup$ You're right - if you assume that "hard to bruteforce" means "not in some rainbow table somewhere, and not something you are likely to randomly generate in the first x billion strings you throw into your huge stack of GPUs", a single SHA256 hash would be safe. $\endgroup$ – Bob Wall Aug 20 '19 at 23:16
-2
$\begingroup$

hard-to-bruteforce string

Without salt, it's not safe.

I know it's all relative, but salting is common practice, easy to implement, and the result is significantly more "safety".

(I was surprised no one mentioned salt. Salt is basically our favorite word in answers)

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Would anyone care to explain why this answer was downvoted? In the future, someone will come here and consider their 12-character string as being "hard to brute force". They must use salt. Regardless of anybody's definition of "hard to brute-force" salt is a must. $\endgroup$ – Todd Feb 11 at 2:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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