web-dev-qa-db-fra.com

Quelles sont les méthodes de salage de mot de passe les plus courantes?

J'ai appris que les hommes du soleil ont utilisé le nom de connexion comme sel pour le hachage de mot de passe. Est-ce une approche commune? Quelles sont les valeurs de sel les plus courantes?

15
Federico Elles

En utilisant le nom de connexion comme sel est courant mais pas vraiment recommandé: cela ne fait que partie du travail. Le point d'un sel doit être aussi unique que possible parmi toutes les instances de mots de passe hachés, afin de contrecarrer toute tentative d'attaque parallèle (attaquant plusieurs mots de passe hachés simultanément, à l'aide de tables précomptes telles que des tables arc-en-ciel ... sont des attaques parallèles). Sur des systèmes distincts, plusieurs utilisateurs peuvent partager le même nom de connexion (il y a tellement de Jones et de Smiths). En outre, un utilisateur donné peut changer son mot de passe tout en gardant son nom; Mais même un ancien mot de passe est précieux pour un attaquant (si seulement parce qu'un ancien mot de passe est souvent un mot de passe que l'utilisateur réutilisera la prochaine fois qu'il est instructuré de changer son mot de passe; De plus, de nombreux utilisateurs utiliseront des mots de passe identiques sur d'autres systèmes) .

Le recommandé moyen de générer un sel consiste à utiliser un bon générateur de nombres aléatoires (idéalement fort cryptographiquement rng) et de produire un groupe d'octets aléatoires. Si le sel est suffisamment long (16 octets ou plus), ceci assurez-vous que l'unicité requise avec une probabilité accablante et sans trop de tracas (pas besoin de rechercher une base de données de sels existants, par exemple).

Nous ne pouvons qu'espérer que cette manière recommandée est également ou deviendra bientôt la voie "la plus courante".

15
Thomas Pornin

Ce qui suit est un système décent pour les mots de passe de salage et de hachage. Il y a un certain nombre de points à garder à l'esprit, c'est pourquoi il semble long. Ceci est un exemple typique de ce que One devrait DOIT en ce qui concerne le salon-hachage; Je ne vais pas aborder ce que fait le soleil.

Les sels et les mots de passe sont mieux traités comme des octets bruts (byte[], unsigned char*, etc.), dans le cas où la langue utilise l'utilisation des cordes de texte dans une autre forme.

Générons un nouveau sel à l'aide d'un générateur de nombres pseudo-aléatoires cryptographiquement fort pour générer le sel. Dans Ruby, cette bibliothèque est appelée commodément securerandom. La plupart des langues viennent également avec un générateur de nombres aléatoires, mais cela n'est pas suffisant pour un sel.

Utilisez SHA256 comme notre algorithme de hachage sous-jacent. Tous les algorithmes de hachage ont une taille de sortie, qui est la taille des bits de la sortie de la fonction de hachage. Tous les algorithmes de hachage ont également une taille de bloc interne caractéristique, qui n'est pas la même que la taille de la sortie. Utilisons un sel aussi grand que la taille du bloc d'algorithme de hachage. Nous faisons cela parce que c'est la plus grande entrées que nous pouvons ajouter au mot de passe avant de le hacher. Si nous utilisons un sel plus grand que la taille du bloc de l'algorithme de hachage sous-jacent, HMAC hacharda simplement le sel d'abord pour obtenir un sel plus petit, réduisant ainsi son entropie, avant de le mélanger avec le mot de passe. La taille du bloc de SHA256 est de 512 bits (= 64 octets), utilisons donc un sel de 64 octets.

Utilisez HMAC - SHA256 au lieu de SHA256 directement, qui fait un peu plus de travail pour garder le mot de passe en sécurité. Nous utiliserons le sel comme paramètre clé sur HMAC-SHA256 au lieu de la préparer au mot de passe. HMAC-SHA256 enveloppe SHA256 et fait un peu de travail supplémentaire pour fusionner le sel avec le mot de passe.

Enfin, les algorithmes de hachage tels que SHA-256 sont conçus pour être rapides. Quel que soit notre code global, il risque de dépenser 1% de son temps authentifiant les utilisateurs et de 99% d'autres choses. Si un attaquant reçoit une copie du fichier de mot de passe, son code est susceptible de dépenser 100% de son temps brut-forçant les mots de passe. Donc, faisons l'algorithme global super lent: pas trop lent qu'il empêche le reste de notre code, mais lentement pour décourager l'attaquant. Prenons un paramètre appelé le facteur de travail (qui pourrait être 16) et itérer HMAC-SHA256 2 ^ temps de facteur de travail (65536 fois dans l'exemple). Si le facteur de travail était 2, alors cela ressemblerait à

HMAC-SHA256(salt,
  HMAC-SHA256(salt,
    HMAC-SHA256(salt,
      HMAC-SHA256(salt,
        password
      )
    )
  )
)

Une solution bonne mais simple à Ruby:

require "securerandom"
require "openssl"

# method for generating a salt and computing a hashed
# version of a password
def salt_hash(password, work_factor)

  # get raw bytes from the password string; only needed in Ruby >= 1.9
  password = password.force_encoding(Encoding::ASCII_8BIT) if defined?(Encoding)

  # use SHA256 as the underlying hash algorithmn
  hash = OpenSSL::Digest::SHA256.new

  # generate a salt as long as the hash algorithm's block size
  # using a cryptographically strong pseudo-random number generator
  salt = SecureRandom.random_bytes(hash.new.block_length)

  # use HMAC, feeding it two parameters: the salt and the
  # underlying hash; since the underlying hash is SHA256,
  # this turns it into HMAC-SHA256
  hmac = OpenSSL::HMAC.new(salt, hash)

  # iterate running HMAC-SHA256 on the password 2^work-factor
  # times to make this function slow enough to discourage an
  # attacker, but not too slow as to make the service unresponsive
  iterations = 2 ** work_factor
  iterations.times do
    password = hmac.digest(password)
  end

  # return the salt and the hashed password to whoever called
  # this method
  {:salt => salt, :hash => password, :work => work_factor}

end

# how to call the method
salt_hash("seekrit", 16)
# and the output would be
 => {:salt => "raw bytes", :hash => "raw bytes", :work => 16}
7
yfeldblum