Rexact
Cheatsheet

Regex bcrypt hash

A bcrypt hash is 60 characters: '$2b$' (version), a two-digit cost, '$', then 53 characters of the './A-Za-z0-9' alphabet (22 salt and 31 digest). OpenBSD's crypt(3) manual page gives the example '$2b$12$FPWWO2RJ3CK4FINTw0Hi8OiPKJcX653gzSS.jqltHFMxyDmmQ0Hqq'. The attempts I read disagree: Spring Security leaves the end unanchored (a 54th character passes) and accepts any two-digit cost, Name-That-Hash does the same, hashID rejects the '$2b$' version that appeared after it. Here's a pattern bounding the cost to 04-31, compared against those attempts.

/^\$2[abxy]\$(?:0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{53}$/
passes 24/24 cases

Comparison of existing patterns

Implementation

const re = new RegExp("^\\$2[abxy]\\$(?:0[4-9]|[12][0-9]|3[01])\\$[./A-Za-z0-9]{53}$", "");
re.test(input);

Limits

  • Valide seulement la FORME : 60 caractères, version, coût 04-31, alphabet. Rien ne prouve qu'une chaîne soit un vrai hachage bcrypt ni qu'elle corresponde à un mot de passe ; la comparaison se fait avec la fonction de la bibliothèque (compare), jamais en réimplémentant le calcul.
  • La borne 04-31 du coût vient des implémentations, pas de la page de manuel OpenBSD ; la version historique « $2$ » (sans lettre) est refusée. Les variantes $2a$/$2x$/$2y$ sont celles de crypt_blowfish ; elles ne sont pas toutes équivalentes (voir la documentation de crypt_blowfish).
  • Les hachages d'autres schémas (Argon2, scrypt, MD5-crypt, SHA-crypt) sont refusés : le préfixe doit être $2a$, $2b$, $2x$ ou $2y$. Aucun mot de passe réel dans les exemples.

Related pages