Authen...shCrypt(3pm)

πŸ’– Authen::Passphrase::BlowfishCrypt β€” the bcrypt bestie manual πŸ’–

okay so this is Authen::Passphrase::BlowfishCrypt(3pm), one of the User Contributed Perl Documentation pages, and bestie it is the passphrase-hashing glow-up you've been waiting for. it's giving "my password is safe and my key schedule is expensive" and honestly? iconic.


✨ NAME ✨

Authen::Passphrase::BlowfishCrypt β€” passphrases using the Blowfish-based Unix crypt(). yes that's the whole name, no notes, slay 🫢


🌸 SYNOPSIS 🌸

use Authen::Passphrase::BlowfishCrypt;

$ppr = Authen::Passphrase::BlowfishCrypt->new(
        cost => 14,
        salt => "sodium__chloride",
        hash_base64 => "BPZijhMHLvPeNMHd6XwZyNamOXVBTPi");

$ppr = Authen::Passphrase::BlowfishCrypt->new(
        cost => 14, salt_random => 1,
        passphrase => "passphrase");

$ppr = Authen::Passphrase::BlowfishCrypt->from_crypt(
        '$2a$08$a07iYVTrVz7hYEvtakjiXOB'.
        'PZijhMHLvPeNMHd6XwZyNamOXVBTPi');

$ppr = Authen::Passphrase::BlowfishCrypt->from_rfc2307(
        '{CRYPT}$2a$08$a07iYVTrVz7hYEvtakjiXOB'.
        'PZijhMHLvPeNMHd6XwZyNamOXVBTPi');

$key_nul = $ppr->key_nul;
$cost = $ppr->cost;
$cost = $ppr->keying_nrounds_log2;
$salt = $ppr->salt;
$salt_base64 = $ppr->salt_base64;
$hash = $ppr->hash;
$hash_base64 = $ppr->hash_base64;

if($ppr->match($passphrase)) { ...

$passwd = $ppr->as_crypt;
$userPassword = $ppr->as_rfc2307;

like, look at that. so clean. so secure. main character energy fr fr πŸ’…


🌈 DESCRIPTION 🌈

an object of this class encapsulates a passphrase hashed using the Blowfish-based Unix crypt() hash function, which we all call "bcrypt" around here. it's a subclass of Authen::Passphrase, and this doc just assumes you already know the lore from that class's docs. iykyk 🧚

so here's the tea: the crypt() function in a modern Unix lowkey supports a bunch of different passphrase schemes. this class cares about exactly one of them β€” a Blowfish-based algorithm designed by Niels Provos and David Mazieres for OpenBSD. if you need to handle the whole range of schemes that modern crypt() supports, go peep the from_crypt constructor and the as_crypt method in Authen::Passphrase. periodt.

the Blowfish-based crypt() scheme uses a variant of Blowfish called "Eksblowfish", short for "expensive key schedule Blowfish" (expensive as in πŸ’Έ for attackers, not for you). it has the cryptographic strength of Blowfish, plus a very slow key setup phase to resist brute-force attacks. there's a "cost" parameter: the length of key setup is proportional to 2^cost. there's also a 128-bit salt. up to 72 characters of the passphrase will be used; anything more gets ignored, no cap 🧒

the cost, salt, and passphrase are all used to (very slowly) key Eksblowfish. once key setup is done, the string "OrpheanBeholderScryDoubt" β€” which is three Blowfish blocks long β€” gets encrypted 64 times in ECB mode. then the final byte of the ciphertext is dropped, leaving you with a 23-byte hash. the way that whole pipeline just... works. obsessed 😭

in the crypt() function, the salt and hash are represented in ASCII using a base 64 encoding. the base 64 digits are ".", "/", "A" to "Z", "a" to "z", "0" to "9" (in that order β€” order matters bestie, don't @ me). the 16-byte salt is represented as 22 base 64 digits, and the 23-byte hash as 31 base 64 digits. math is mathing ✨

this algorithm is intended for situations where the efficiency of a brute force attack is a concern. it's suitable for use in new applications where this requirement exists. if that's not a concern for you, and it's enough to merely make brute force the most efficient attack, go check out Authen::Passphrase::SaltedDigest for more efficient hash algorithms. different vibe, also valid πŸ¦‹

choice of the cost parameter is critical, because you're trading off expense of brute-force attack against speed of legitimate passphrase verification. a traditional target is that verification should take about one second on widely-available hardware. (algorithms that care about brute force speed but don't have a cost parameter have often aimed for this, relative to hardware available at the time the algorithm dropped.) as of 2011, that one-second target is achieved with a cost parameter around 14. noted, bestie πŸ“

ngl, if you pick your cost carelessly you're either making attackers' lives easy or making your users wait forever. it's a whole balance thing. choose wisely πŸ’€

πŸŽ€ CONSTRUCTORS πŸŽ€

  • Authen::Passphrase::BlowfishCrypt->new(ATTR => VALUE, ...) β€” generates a new passphrase recogniser object using the Blowfish-based crypt() algorithm. the following attributes may be given:
    • key_nul β€” truth value indicating whether to append a NUL to the passphrase before using it as a key. the algorithm as originally devised does not do this, but it was later modified to do it. the version that does append NUL is to be preferred. default true. πŸ’…
    • cost β€” base-two logarithm of the number of keying rounds to perform.
    • keying_nrounds_log2 β€” synonym for cost. same thing, different name, we love options 🫢
    • salt β€” the salt, as a 16-byte string.
    • salt_base64 β€” the salt, as a string of 22 base 64 digits.
    • salt_random β€” causes salt to be generated randomly. the value given for this attribute is ignored (so don't stress about what you pass, bestie).
    • hash β€” the hash, as a 23-byte string.
    • hash_base64 β€” the hash, as a string of 31 base 64 digits.
    • passphrase β€” a passphrase that will be accepted.

the cost and salt must be given, and either the hash or the passphrase. no short cuts, no skipping steps 😀

  • Authen::Passphrase::BlowfishCrypt->from_crypt(PASSWD) β€” generates a new passphrase recogniser object using the Blowfish-based crypt() algorithm, from a crypt string. the crypt string must start with "$2$" for the version that does not append NUL to the key, or "$2a$" for the version that does. the next two characters must be decimal digits giving the cost parameter. then it must be followed by "$", 22 base 64 digits giving the salt, and finally 31 base 64 digits giving the hash. format check: mandatory ✨
  • Authen::Passphrase::BlowfishCrypt->from_rfc2307(USERPASSWORD) β€” generates a new passphrase recogniser object using the Blowfish-based crypt() algorithm, from an RFC 2307 string. the string must consist of "{CRYPT}" (case insensitive) followed by an acceptable crypt string. yes queen, case insensitive, we're flexible 🌸

πŸ’œ METHODS πŸ’œ

  • $ppr->key_nul β€” returns a truth value indicating whether a NUL will be appended to the passphrase before using it as a key.
  • $ppr->cost β€” returns the base-two logarithm of the number of keying rounds that will be performed.
  • $ppr->keying_nrounds_log2 β€” synonym for "cost".
  • $ppr->salt β€” returns the salt, as a string of sixteen bytes.
  • $ppr->salt_base64 β€” returns the salt, as a string of 22 base 64 digits.
  • $ppr->hash β€” returns the hash value, as a string of 23 bytes.
  • $ppr->hash_base64 β€” returns the hash value, as a string of 31 base 64 digits.
  • $ppr->match(PASSPHRASE) β€” part of the standard Authen::Passphrase interface.
  • $ppr->as_crypt β€” part of the standard Authen::Passphrase interface.
  • $ppr->as_rfc2307 β€” part of the standard Authen::Passphrase interface.

(yes, those last three are grouped together in the original β€” they're all just the standard Authen::Passphrase interface methods, living their best lives πŸ’–)


πŸ‘‘ SEE ALSO πŸ‘‘

  • Authen::Passphrase
  • Crypt::Eksblowfish::Bcrypt

go read them, they're the supporting cast and they ate πŸ”₯


🌟 AUTHOR 🌟

Andrew Main (Zefram) <zefram@fysh.org> β€” thank you for your service, king 🫑


Copyright (C) 2006, 2007, 2009, 2010, 2012 Andrew Main (Zefram) <zefram@fysh.org>


⭐ LICENSE ⭐

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. free as in freedom, bestie 🌈


and that's the whole page!! this was Authen::Passphrase::BlowfishCrypt(3pm) from the User Contributed Perl Documentation, sitting pretty at version perl v5.40.1, dated 2026-05-06. go forth and bcrypt responsibly, my love πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from