Remix.run Logo
alright2565 2 hours ago

If you are needing to version your password hashes, then you are likely doing them incorrectly and not using a proper computationally-hard hashing algorithm.

For example, with unsuitable algorithms like sha256, you get this, which doesn't have a version field:

    import hashlib; print(f"MD5:      {hashlib.md5(b'password').hexdigest()}")
    print(f"SHA-256:  {hashlib.sha256(b'password').hexdigest()}")


    MD5:      5f4dcc3b5aa765d61d8327deb882cf99
    SHA-256:  5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
But if you use a proper password hash, then your hashing library will automatically take care of versioning your hash, and you can just treat it as an opaque blob:

    import argon2; print(f"Argon2:   {argon2.PasswordHasher().hash('password')}")
    import bcrypt; print(f"bcrypt:   {bcrypt.hashpw(b'password', bcrypt.gensalt()).decode()}")
    from passlib.hash import scrypt; print(f"scrypt:   {scrypt.hash('password')}")


    Argon2:   $argon2id$v=19$m=65536,t=3,p=4$LZ/H9PWV2UV3YTgF3Ixrig$aXEtfkmdCMXX46a0ZiE0XjKABfJSgCHA4HmtlJzautU
    bcrypt:   $2b$12$xqsibRw1wikgk9qhce0CGO9G7k7j2nfpxCmmasmUoGX4Rt0B5umuG
    scrypt:   $scrypt$ln=16,r=8,p=1$/V8rpRTCmDOGcA5hjPFeCw$6N1e9QmxuwqbPJb4NjpGib5FxxILGoXmUX90lCXKXD4
This isn't a new thing, and as far as I'm aware, it's derived from the old apache htpasswd format (although no one else uses the leading colon)

    $ htpasswd -bnBC 10 "" password
    :$2y$10$Bh67PQAd4rqAkbFraTKZ/egfHdN392tyQ3I1U6VnjZhLoQLD3YzRe