Je souhaite stocker un mot de passe haché (à l'aide de BCrypt) dans une base de données. Quel serait le bon type pour cela et quelle serait la bonne longueur? Les mots de passe hachés avec BCrypt sont-ils toujours de la même longueur?
EDIT
Exemple de hachage:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
Après le hachage de certains mots de passe, il semble que BCrypt génère toujours des hachages de 60 caractères.
EDIT 2
Désolé de ne pas mentionner la mise en œuvre. J'utilise jBCrypt .
Le format de cryptage modulaire pour bcrypt est composé de
$2$
, $2a$
ou $2y$
identifiant le algorithme de hachage et format$
.
, /
, 0
– 9
, A
– Z
, a
– z
différent de alphabet standard à la Base 64 ) composé de: Ainsi, la longueur totale est respectivement de 59 ou 60 octets.
Si vous utilisez le format 2a, vous aurez besoin de 60 octets. Et donc pour MySQL, je vous recommande d’utiliser CHAR(60) BINARY
OR BINARY(60)
(voir Le _ bin et binaire Collations pour des informations sur la différence).
CHAR
n'est pas binaire sécurisé et l'égalité ne dépend pas uniquement de la valeur d'octet, mais du classement effectif; dans le pire des cas, A
est traité comme égal à a
. Voir Les _bin
et binary
Classements pour plus d'informations.
Un hachage Bcrypt peut être stocké dans une colonne BINARY(40)
.
BINARY(60)
, comme le suggèrent les autres réponses, est le choix le plus simple et le plus naturel. Toutefois, si vous souhaitez optimiser l'efficacité du stockage, vous pouvez économiser 20 octets en déconstruisant sans perte le hachage. Je l'ai documenté plus en détail sur GitHub: https://github.com/ademarre/binary-mcf
Les hachages Bcrypt suivent une structure appelée format de cryptage modulaire (MCF). Binary MCF (BMCF) décode ces représentations de hachage textuelles en une structure binaire plus compacte. Dans le cas de Bcrypt, le hachage binaire résultant est de 40 octets.
Gumbo a bien expliqué les quatre composants d'un hachage Bcrypt MCF:
$<id>$<cost>$<salt><digest>
Le décodage en BMCF se déroule comme suit:
$<id>$
peut être représenté en 3 bits.<cost>$
, 04-31, peut être représenté sur 5 bits. Rassemblez-les pour 1 octet.1 + 16 + 23
Vous pouvez en savoir plus sur le lien ci-dessus ou examiner mon PHP implémentation , également sur GitHub.
Si vous utilisez password_hash()
avec PHP avec l'algorithme PASSWORD_DEFAULT
pour générer le hachage bcrypt (ce qui, je suppose, représente un pourcentage élevé de personnes lisant cette question), n'oubliez pas que dans les future password_hash()
pourrait utiliser un algorithme différent par défaut, ce qui pourrait donc affecter la longueur du hachage (mais il ne sera pas forcément plus long).
De la page de manuel:
Notez que cette constante est conçue pour évoluer dans le temps à mesure que de nouveaux algorithmes plus puissants sont ajoutés à PHP. Pour cette raison, la longueur du résultat de l'utilisation de cet identifiant peut changer dans le temps. Par conséquent, , il est recommandé de stocker le résultat dans une colonne de base de données pouvant contenir plus de 60 caractères (255 caractères seraient un bon choix).
Avec bcrypt, même si vous avez 1 milliard d'utilisateurs (c'est-à-dire que vous êtes actuellement en concurrence avec Facebook) pour stocker des mots de passe hachés de 255 octets, il ne consisterait qu'environ 255 Go de données, environ la taille d'un disque dur SSD de petite taille. Il est extrêmement improbable que le stockage du hachage du mot de passe constitue le goulot d'étranglement de votre application. Cependant, au hasard cet espace de stockage est un problème pour une raison quelconque, vous pouvez utiliser PASSWORD_BCRYPT
pour forcer password_hash()
à utiliser bcrypt, même si ce n'est pas le défaut. Veillez simplement à rester informé des vulnérabilités trouvées dans bcrypt et consultez les notes de publication chaque fois qu'une nouvelle version PHP est publiée. Si l’algorithme par défaut est modifié, il serait bon d’examiner pourquoi et de décider en connaissance de cause d’utiliser ou non le nouvel algorithme.
Je ne pense pas que vous puissiez enregistrer ce que vous faites de mieux, comme vous pouvez le faire par exemple avec un hachage MD5.
Je pense que votre meilleur pari est de le stocker en tant que CHAR(60)
car il est toujours long de 60 caractères