Est-ce que quelqu'un peut expliquer comment BCrypt vérifie un hash?

j'utilise C# et BCrypt.Net pour effacer mes mots de passe.

par exemple:

string salt = BCrypt.Net.BCrypt.GenerateSalt(6);
var hashedPassword = BCrypt.Net.BCrypt.HashPassword("password", salt);

//This evaluates to True. How? I'm not telling it the salt anywhere, nor
//is it a member of a BCrypt instance because there IS NO BCRYPT INSTANCE.
Console.WriteLine(BCrypt.Net.BCrypt.Verify("password", hashedPassword));
Console.WriteLine(hashedPassword);

comment bcrypt vérifie-t-il le mot de passe avec le hachage s'il n'enregistre pas le sel n'importe où. La seule idée que j'ai, c'est que ça ajoute du sel au bout du hash.

est-ce une hypothèse correcte?

24
demandé sur Michael La Voie 2011-03-22 18:41:16

2 réponses

comment bcrypt vérifie-t-il le mot de passe avec le hachage s'il n'enregistre le sel nulle part?

il est clair qu'il ne fait rien de tel. Le sel doit être enregistré quelque part.

regardons les schémas de cryptage de mot de passe sur Wikipedia. De http://en.wikipedia.org/wiki/Crypt_ (Unix) :

La sortie de la fonction n'est pas seulement le hash: c'est un chaîne de texte qui encode également le sel et identifie l'algorithme de hachage utilisé.

alternativement, une réponse à votre question précédente à ce sujet incluait un lien vers le code source . plutôt que de demander à internet de lire le code source pour vous, vous pouvez toujours choisir de le lire vous-même. qui obtiendrait probablement votre réponse plus rapidement. La section pertinente de la source le code est:

    StringBuilder rs = new StringBuilder();
    rs.Append("");
    if (minor >= 'a') {
        rs.Append(minor);
    }
    rs.Append('$');
    if (rounds < 10) {
        rs.Append('0');
    }
    rs.Append(rounds);
    rs.Append('$');
    rs.Append(EncodeBase64(saltBytes, saltBytes.Length));
    rs.Append(EncodeBase64(hashed,(bf_crypt_ciphertext.Length * 4) - 1));
    return rs.ToString();

il est clair que la chaîne retournée est une information de version, suivie du nombre de tours utilisés, suivi du sel encodé sous le nom de base64, suivi du hachage encodé sous le nom de base64.

25
répondu Eric Lippert 2017-05-23 12:10:27

Un BCrypt de hachage chaîne ressemble à:

a$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
$==$==$======================-------------------------------

  • 2a : identificateur D'algorithme (bcrypt, UTF8 encoded password, null terminated)
  • 10 : facteur de coût (2 10 = 1,024 rounds)
  • Ro0CUfOqk6cXEKf3dyaM7O : sel encodé OpenBSD-Base64 (22 caractères, 16 octets)
  • hSCvnwM9s4wIX9JeLapehKK5YdLxKcm : OpenBSD-encodées en Base64 de hachage (31 caractères, 24 octets)

Edit : je viens de remarquer que ces mots correspondent exactement. je devais partager:

a$TwentytwocharactersaltThirtyonecharacterspasswordhash
$==$==$======================-------------------------------

BCrypt ne créer un 24-octet binaire de hachage, à l'aide de 16 octets de sel. Vous êtes libre de stocker le hash binaire et le sel comme vous le souhaitez; rien il est dit que vous avez à la base-64 encodez-le dans une chaîne.

mais BCrypt a été créé par des gars qui travaillaient sur OpenBSD. OpenBSD définit déjà un format pour leur fichier de mots de passe:

$ [HashAlgorithmIdentifier] $ [AlgorithmSpecificData]

cela signifie que la "spécification bcrypt" est inexorablement lié au format de fichier de mots de passe OpenBSD. Et chaque fois que quelqu'un crée un "bcrypt hash" ils toujours convertissez-le en une chaîne ISO-8859-1 du format:

$ 2a $ [Cost] $ [Base64Salt][Base64Hash]

quelques points importants:

  • 2a est le identificateur alogithm
    • 1: MD5
    • 2: Début de bcrypt, qui a eu la confusion sur les mots de passe encodage sont dans (obsolète)
    • 2a: bcrypt actuel, qui spécifie les mots de passe encodés UTF-8
  • coût est un facteur de coût utilisé dans le calcul du hash. La valeur" courante " est 10, ce qui signifie que la configuration de la clé interne passe par 1024 tours
    • 10: 2 10 = 1,024 itérations
    • 11: 2 11 = 2,048 itérations
    • 12: 2 12 = 4,096 itérations
  • l'algorithme de base64 utilisé par le fichier de mots de passe OpenBSD n'est pas le même que celui utilisé par tout le monde ; ils ont leur propre:

    Regular Base64 Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
        BSD Base64 Alphabet: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
    

    de sorte que toute implémentation de bcrypt ne peut utiliser aucune bibliothèque


armé de cette connaissance, vous pouvez maintenant vérifier un mot de passe correctbatteryhorsestapler contre le hachage sauvé:

a$mACnM5lzNigHMaf7O1py1O3vlf6.BA8k8x3IoJ.Tq3IB/2e7g61Km
79
répondu Ian Boyd 2013-06-10 15:28:23