String#crypt deprecated
str.crypt(salt_str) Overview
String#crypt encrypts the receiver string using the POSIX crypt(3) function with the provided salt. The salt is a string of at least 2 bytes whose format determines which hashing algorithm gets used.
This method has been part of Ruby’s standard library since very early versions, but it is deprecated in Ruby 2.5 and later (Feature #14915). Ruby now emits a deprecation warning and delegates to the string-crypt gem when it is available. Removal from core is planned.
For new code, install the gem explicitly:
gem install string-crypt
require 'string/crypt'
Salt Format
The salt string controls algorithm selection through its prefix. Understanding the prefix is critical — using the wrong one silently produces weak or broken output.
| Salt Prefix | Algorithm | Notes |
|---|---|---|
| (no prefix, 2 chars) | Traditional DES | 2^56 keyspace — trivially brute-forced |
$1$ | MD5 | Author abandoned it — do not use |
$3$ | MD4/ATH | Completely broken — avoid |
$5$ | SHA-256 | Acceptable for non-password use |
$6$ | SHA-512 | Better option for hash-based applications |
$2a$ | Blowfish (BSD) | Used by BSD crypt_b |
Modular formats also support a rounds= parameter to increase computational cost:
"$6$rounds=5000$mysecretsalt$"
The rounds= parameter is optional. Its default value varies by operating system.
Basic Usage
Without the gem, or with traditional DES (the default when using a 2-character salt):
"hello".crypt("ab")
# => "RXkJ8M2N8vGjQ" # output varies by OS
With SHA-512 modular format (requires the string-crypt gem on some systems):
require 'string/crypt'
"hello".crypt("$6$rounds=5000$mysecretsalt$")
# => "$6$rounds=5000$mysecretsalt$o.jP9zGQdJ..."
With SHA-256:
"hello".crypt("$5$rounds=1000$saltvalue$")
# => "$5$rounds=1000$saltvalue$eG2IUf9O1..."
Deprecation Warning
Ruby 2.5 and later emit a deprecation warning when String#crypt is called:
$ ruby -e '"foo".crypt("ab")'
-e:1: warning: String#crypt is deprecated; use string-crypt gem
=> "ab9QbfRTt7p2A"
The warning appears on stderr. It does not stop execution. Ruby delegates to the string-crypt gem when it is available, so installing the gem silences the warning while keeping the same interface.
Salt Requirements
The salt argument must be at least 2 bytes:
"hello".crypt("a")
# => ArgumentError: salt too short (need >=2 bytes)
A salt that is too short raises an ArgumentError. A malformed salt — such as a typo in the prefix — does not raise an error. It silently produces an incorrect or weak hash:
# Typo in rounds parameter: "round" instead of "rounds"
"foo".crypt("$5$round=1000$salt$")
# => silently wrong hash, no error raised
Gotchas and Platform Differences
OS dependency. crypt(3) is a system call, so the supported algorithms and output format vary by operating system. A hash produced on Linux cannot be verified on macOS or Windows. This is especially important for cross-platform applications.
macOS limitations. On macOS, crypt(3) does not support modular crypt modes ($5$, $6$, $2a$). It always falls back to the traditional DES algorithm, regardless of what salt prefix you provide. The method will not raise an error — it just ignores the prefix and produces a DES hash.
Thread safety. On some operating systems, crypt(3) is not thread-safe. Ruby’s implementation adds a mutex to protect the call, but this introduces overhead in multi-threaded code and does not eliminate platform-level race conditions.
Weak default. When no prefix is used (or a 2-character salt is given), the method uses traditional DES. This has a keyspace of only 2^56 — easily brute-forced on modern hardware. Never use the default for anything security-related.
MD5 is abandoned. The $1$ prefix uses MD5, whose author officially abandoned it for password hashing. It is retained for legacy compatibility only.
When Not to Use This Method
- Password storage in new applications — use
bcrypt,argon2, orscryptinstead - Any security-sensitive hashing — DES and MD5 are broken
- Cross-platform applications — algorithm support varies
- Anything requiring portability between operating systems