--- name: crypt signature: 'crypt PLAINTEXT,SALT' since: 5.0 status: documented categories: ["SCALARs and strings"] --- ```{index} single: crypt; Perl built-in ``` *[SCALARs and strings](../perlfunc-by-category)* # crypt One-way `passwd(5)`-style hashing of a plaintext string with a salt. `crypt` is a thin wrapper over the system C library's `crypt(3)` function. It turns `PLAINTEXT` and `SALT` into a short string — a *digest* — and returns it. The same `PLAINTEXT` and `SALT` always produce the same digest; small changes in either produce a completely different digest. There is no inverse function: you cannot recover `PLAINTEXT` from a digest. :::{warning} `crypt` is **not a general-purpose encryption function**, despite the name. It cannot be undone. It is also **not a modern password hash** on most traditional configurations — the historical Unix scheme considers only the first eight bytes of `PLAINTEXT` and produces a 13-byte digest over a 12-bit salt, which is unsuitable for protecting passwords against contemporary attackers. What `crypt` is good for is verifying a user-supplied string against an already-stored digest produced by the same system's `crypt`. For anything else — encryption, key derivation, or hashing large data — use a real cryptographic library. See *See also* below. ::: ## Synopsis ```perl crypt PLAINTEXT, SALT ``` Both arguments are strings. The return value is a string digest. ## What you get back A string whose exact shape depends on the host's `crypt(3)` implementation. Traditionally it is 13 bytes: two bytes of salt followed by 11 bytes from the set `[./0-9A-Za-z]`. Modern glibc, musl, and BSD libcs accept extended salts that select stronger schemes (MD5, SHA-256, SHA-512, bcrypt, yescrypt) and return longer digests in the `$id$salt$hash` `passwd`-file format. **Treat the digest as opaque.** Do not parse it, do not assume a length, and do not assume which bytes of `SALT` the implementation consumed. The correct way to verify a plaintext against an existing digest is to pass the digest itself back in as the salt: ```perl if (crypt($plain, $digest) eq $digest) { ... } ``` The salt used to create the digest is embedded in the digest, so this re-runs the same scheme with the same parameters on the candidate plaintext. Code written this way works with the classical DES scheme and with every modern extension a given `crypt(3)` exposes, without having to know which one produced the stored digest. ## Global state it touches `crypt` does not read or write any Perl special variable. On Unicode input it may emit a fatal `Wide character in crypt` error (see *Edge cases*). ## Examples Verify a password against a stored `passwd`-style digest: ```perl my $stored = (getpwuid($<))[1]; # encrypted field from passwd print "Password: "; chomp(my $word = ); if (crypt($word, $stored) eq $stored) { print "ok\n"; } else { die "Sorry...\n"; } ``` Create a fresh digest for a new password using a random two-character salt from the classical alphabet. The set is only a recommendation; the exact characters accepted in a salt are whatever the host `crypt(3)` allows, and Perl imposes no restriction of its own: ```perl my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); my $salt = $chars[rand 64] . $chars[rand 64]; my $hash = crypt($plaintext, $salt); ``` Request a specific modern scheme by using an extended salt (glibc and compatible libcs). The `$id$` prefix selects the algorithm — `$1$` is MD5-crypt, `$5$` is SHA-256-crypt, `$6$` is SHA-512-crypt, `$2b$` is bcrypt where supported: ```perl my $hash = crypt($plaintext, '$6$rounds=100000$' . $random_salt); ``` Re-verify using the stored digest as the salt — scheme-agnostic: ```perl my $candidate = crypt($plaintext, $stored_digest); my $match = $candidate eq $stored_digest; ``` Constant-time comparison of the two digests is still the caller's responsibility; plain `eq` leaks timing information. If the threat model cares, compare byte-by-byte with a loop that does not short-circuit, or use a comparison routine from a crypto module. ## Edge cases - **First-8-byte truncation on classical DES.** On traditional Unix `crypt(3)`, only the first eight bytes of `PLAINTEXT` affect the digest: `crypt("password123", $s)` and `crypt("password456", $s)` collide. Extended schemes (`$1$`, `$5$`, `$6$`, `$2b$`, …) do not have this limit, but the classical scheme is what you get from an unprefixed two-byte salt. - **Salt-length assumptions are wrong.** Do not assume `substr($digest,0,2)` is the salt. Extended digests carry the salt in a different position and length. Re-use the full digest as the salt argument (`crypt($plain, $digest)`) and let `crypt(3)` parse it. - **Unicode input.** If `PLAINTEXT` or `SALT` contains characters above codepoint 255, Perl attempts to downgrade a copy of the string to bytes before calling `crypt(3)`. If every character fits in a byte, the downgrade succeeds silently. If any character does not, `crypt` dies with `Wide character in crypt`. Encode explicitly (e.g. `Encode::encode_utf8`) if your plaintext might contain wide characters. - **Unsupported scheme returns failure.** Passing a `$id$` prefix the host `crypt(3)` does not understand typically returns [`undef`](undef) or a short string starting with `*0` or `*1`. Always check the return shape before using it. - **`crypt(3)` may be absent or restricted.** On a small number of hosts the library function has been removed or replaced with a stub for export-control reasons. `crypt` in Perl is only as capable as the underlying libc call; if the libc call is a stub, so is this. - **Not suitable for hashing large data.** `crypt` ignores most of its input on the classical scheme and is slow per call on the stretched schemes. It is the wrong tool for checksumming files or building content-addressable storage. ## Differences from upstream Fully compatible with upstream Perl 5.42. pperl dispatches to the host `crypt(3)` the same way perl5 does, so the accepted salt formats and the exact digest shape match whatever the system library produces — including the availability of `$1$`/`$5$`/`$6$`/ `$2b$` extended schemes. ## See also - `Digest::MD5` — MD5-128 over arbitrary byte strings; use for fingerprinting data, not for password storage - `Digest::SHA` — SHA-1/2 family digests; use for integrity checks and as a building block for HMAC and key derivation - `Crypt::Bcrypt`, `Crypt::Argon2`, `Crypt::Passphrase` — CPAN modules for modern password hashing; prefer these over `crypt` for any new password-verification code - `Crypt::Eksblowfish`, `Crypt::ScryptKDF` — CPAN modules for bcrypt and scrypt-based key derivation - [`getpwuid`](getpwuid) — fetch the encrypted-password field from the local `passwd` database; its seventh field is the digest you pass as `SALT` when verifying - [`chomp`](chomp) — remove the trailing newline from a password read with `` before passing it to `crypt`