0

I've been learning about cryptography lately and how slow hashes are the best to prevent brute-force attacks. I tried using SHA-256 in C++ implemented from this resource, which is fantastic, but it's very very fast. I changed up one of my brute-force programs to search for the SHA-256 hash of the password to see if we got a match, and it didn't take as long as I could've hoped. Currently with the (relatively very slow) brute force program I made myself, we get a table like this:

Password | runtime plaintext | passwords/sec plaintext | runtime SHA-256 | passwords/sec SHA-256

   zzz   |    1.18 seconds   |          149,985        |   6.2 seconds   | 28,564

Obviously, a skilled attacker would have a program that guesses more than 28,000 passwords/second at max speed. I tried using Bcrypt from OpenWall, but I couldn't find any good documentation on how to use it in my actual program!

Is there any way to slow down my hashing method, or should I use another way to hash in C++? If the latter, please let me know which resources you think could help me - I'm just starting out in cryptography and don't know much. Thanks!!!

John Smith
  • 21
  • 4

2 Answers2

1

To slow down hashing call the hash algorithm multiple times chaining the output. So the output from the previous hash is the input the the next iteration. Do this say 5,000 times (test this to see how slow) to produce a slower hash. This relies on there being no known way to short-cut a recursive hash. Using this approach you can slow down hashing to any degree you require, say to 1 hash per second on your test hardware.

Richard Critten
  • 2,138
  • 3
  • 13
  • 16
  • While this is the essence of proper password hashing there is no reason to invent your own method. There are plenty of good password hash algorithms to choose from, such as bcrypt, scrypt, argon2. The fact that the OP can't find documentation for a particular library isn't a good enough reason to invent own crypto; this suggestion here doesn't seed the hash, for instance. – Peter Jul 13 '19 at 13:45
  • Assuming you hashed a hash and hashed a hash (and so on for a few hundred times), would the attacker then need to reproduce those steps, or could shortcuts be taken? – John Smith Jul 13 '19 at 19:39
0

Hashing is a very popular method of creating a fixed length blob of any text because of their excellent properties of not causing a collision in practice almost all the time. One of the popular usage of SHA256 is in the TLS cipher suites.

This makes it attractive to speed up the SHA implementations for programmers to make their software compute the SHA faster somehow. Also, it makes it more attractive for Chip designers like Intel and AMD to make their CPU compute SHA faster (they can then say, our chips are faster in making TLS connections). Because of this, Intel and now AMD built native instructions to compute SHA. This made things blazingly fast because operations are now cheaper and consume less power because of the CPU running fewer cycles. This helps the attackers as well as they can test so many SHA hashes for brute forcing.

$ openssl speed sha256 # LibreSSL
Doing sha256 for 3s on 16 size blocks: 9747573 sha256's in 2.98s
Doing sha256 for 3s on 64 size blocks: 5266867 sha256's in 2.99s
Doing sha256 for 3s on 256 size blocks: 2241999 sha256's in 2.98s
Doing sha256 for 3s on 1024 size blocks: 684841 sha256's in 2.98s
Doing sha256 for 3s on 8192 size blocks: 90002 sha256's in 2.99s
LibreSSL 2.6.5
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
sha256           52335.96k   112735.61k   192601.26k   235327.91k   246587.42k
$ fopenssl speed sha256 # OpenSSL 
Doing sha256 for 3s on 16 size blocks: 12397094 sha256's in 2.98s
Doing sha256 for 3s on 64 size blocks: 6895826 sha256's in 2.98s
Doing sha256 for 3s on 256 size blocks: 2950209 sha256's in 2.98s
Doing sha256 for 3s on 1024 size blocks: 909184 sha256's in 2.98s
Doing sha256 for 3s on 8192 size blocks: 122122 sha256's in 2.99s
OpenSSL 1.0.2r  26 Feb 2019
compiler: clang -I. -I.. -I../include  -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
sha256           66561.58k   148098.28k   253440.77k   312417.59k   334589.77k

You can see that the speeds are blazing when it comes to computing SHA256 hashes. These benchmarks were run on

$ sysctl -n machdep.cpu.brand_string
Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz

In the options for clang there is a switch -DSHA256_ASM which I believe tells the compiler to use something like sha256-ssse3-asm.S, I am not entirely sure about the option, if anyone could elaborate. This would make SHA256 computation fast.

To answer your question, you could use a slower hash function like Tarsnap/scrypt which can be tuned to use more CPU or Memory based on your attacker. The brute forcing techniques can use either a CPU or a GPU which can accelerate the hashing rate to more than a billion hashes per second (Hashcat on GPUs). Scrypt can be tuned to use higher amount of memory rendering all the compute power useless thus stopping brute force attacks.

prateeknischal
  • 752
  • 4
  • 12