Lorsque qu’on se fait dumper sa base de login/mot de passe, le plus gros problème c’est de permettre à ses utilisateurs d’avoir le temps de changer leur mot de passe avant qu’il ne se trouve bruteforcé.
Ici on ne parle pas des problèmes de sécurité liés aux risques de collisions des fonctions de hachage (MD5 par exemple), mais plutôt de la capacité à ralentir des serveurs de bruteforce, sachant que certains vont jusqu’à plusieurs dizaines de “giga hash” par seconde. Le mot de passe comporte une SALT et ne se trouve pas dans un dictionnaire (sinon le cassage est rapide).
Le test a été fait avec les fonctions de hachage et autres algorithmes de cryptographie suivants :
- MD5
- SHA-1
- SHA256
- SSHA256 (Spread SHA256) =>
Hash(0) = "" ; 1000 fois faire : Hash(n) = SHA256(Hash(n-1) + SALT + password)
- BCRYPT
- SCRYPT
Voici un petit script en Ruby qui mesure le temps de calcul entre les différentes méthodes :
#!/usr/bin/env ruby
#encoding: UTF-8
require 'benchmark'
require 'scrypt'
require 'bcrypt'
require 'digest'
password = ARGV.shift
n=10000
salt = SCrypt::Engine.generate_salt
saltbcrypt = BCrypt::Engine.generate_salt
Benchmark.bm(17) do |x|
x.report(" MD5 :") { n.times do ; h = Digest::MD5.digest(password+salt) ; end }
x.report(" SHA1 :") { n.times do ; h = Digest::SHA1.digest(password+salt) ; end }
x.report(" SHA256 :") { n.times do ; h = Digest::SHA256.digest(password+salt) ; end }
x.report(" SSHA256 :") { n.times do ; 1000.times do ; h = "" ; h = Digest::SHA256.digest(h+password+salt) ; end ; end }
x.report(" Bcrypt :") { n.times do ; h = BCrypt::Engine.hash_secret(password, saltbcrypt) ; end }
x.report(" Scrypt :") { n.times do ; h = SCrypt::Engine.hash_secret(password, salt) ; end }
end
et le résultat de son exécution :
user system total real MD5 : 0.010000 0.000000 0.010000 ( 0.014651) SHA1 : 0.020000 0.000000 0.020000 ( 0.017404) SHA256 : 0.020000 0.000000 0.020000 ( 0.017957) SSHA256 : 19.240000 0.000000 19.240000 ( 19.272748) Bcrypt : 665.640000 0.010000 665.650000 ( 666.651504) Scrypt : 1357.120000 2.760000 1359.880000 (1361.951263)
L’utilisation de SCRYPT est sans conteste à recommander par rapport aux autres méthodes, si on compare simplement MD5 et SCRYPT le rapport est de l’ordre de 100’000. SCRYPT a aussi une empreinte mémoire non négligeable.