PHP - Crypt - Manual
PHP - Crypt - Manual
Documentation
Get Involved
Help
Search docs
PHP 8.4.6 Released!
Getting Started
Introduction
A simple tutorial
Language Reference
Basic syntax
Types
Variables
Constants
Expressions
Operators
Control Structures
Functions
Classes and Objects
Namespaces
Enumerations
Errors
Exceptions
Fibers
Generators
Attributes
References Explained
Predefined Variables
Predefined Exceptions
Predefined Interfaces and Classes
Predefined Attributes
Context options and parameters
Supported Protocols and Wrappers
Security
Introduction
General considerations
Installed as CGI binary
Installed as an Apache module
Session Security
Filesystem Security
Database Security
Error Reporting
User Submitted Data
Hiding PHP
Keeping Current
Features
HTTP authentication with PHP
Cookies
Sessions
Handling file uploads
Using remote files
Connection handling
Persistent Database Connections
Command line usage
Garbage Collection
DTrace Dynamic Tracing
Function Reference
Affecting PHP's Behaviour
Audio Formats Manipulation
Authentication Services
Command Line Specific Extensions
Compression and Archive Extensions
Cryptography Extensions
Database Extensions
Date and Time Related Extensions
File System Related Extensions
Human Language and Character Encoding Support
Image Processing and Generation
Mail Related Extensions
Mathematical Extensions
Non-Text MIME Output
Process Control Extensions
Other Basic Extensions
Other Services
Search Engine Extensions
Server Specific Extensions
Session Extensions
Text Processing
Variable and Type Related Extensions
Web Services
Windows Only Extensions
XML Manipulation
GUI Extensions
Keyboard Shortcuts
?
This help
j
Next menu item
k
Previous menu item
gp
Previous man page
gn
Next man page
G
Scroll to bottom
gg
Scroll to top
gh
Goto homepage
gs
Goto search
(current page)
/
Focus search box
echo »
« crc32
PHP Manual
Function Reference
Text Processing
Strings
String Functions
crypt
(PHP 4, PHP 5, PHP 7, PHP 8)
Description ¶
crypt(#[\SensitiveParameter] string $string, string $salt): string
crypt() will return a hashed string using the standard Unix DES-based algorithm or alternative algorithms. password_verify() is
compatible with crypt(). Therefore, password hashes created by crypt() can be used with password_verify().
Prior to PHP 8.0.0, the salt parameter was optional. However, crypt() creates a weak hash without the salt, and raises an E_NOTICE
error without it. Make sure to specify a strong enough salt for better security.
password_hash() uses a strong hash, generates a strong salt, and applies proper rounds automatically. password_hash() is a simple
crypt() wrapper and compatible with existing password hashes. Use of password_hash() is encouraged.
The hash type is triggered by the salt argument. If no salt is provided, PHP will auto-generate either a standard two character (DES)
salt, or a twelve character (MD5), depending on the availability of MD5 crypt(). PHP sets a constant named CRYPT_SALT_LENGTH
which indicates the longest valid salt allowed by the available hashes.
The standard DES-based crypt() returns the salt as the first two characters of the output. It also only uses the first eight characters of
string, so longer strings that start with the same eight characters will generate the same result (when the same salt is used).
CRYPT_STD_DES - Standard DES-based hash with a two character salt from the alphabet "./0-9A-Za-z". Using invalid characters
in the salt will cause crypt() to fail.
CRYPT_EXT_DES - Extended DES-based hash. The "salt" is a 9-character string consisting of an underscore followed by 4
characters of iteration count and 4 characters of salt. Each of these 4-character strings encode 24 bits, least significant
character first. The values 0 to 63 are encoded as ./0-9A-Za-z. Using invalid characters in the salt will cause crypt() to fail.
CRYPT_MD5 - MD5 hashing with a twelve character salt starting with $1$
CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22
characters from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt() to return a
zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-
based hashing algorithm and must be in range 04-31, values outside this range will cause crypt() to fail. "$2x$" hashes are
potentially weak; "$2a$" hashes are compatible and mitigate this weakness. For new hashes, "$2y$" should be used.
CRYPT_SHA256 - SHA-256 hash with a sixteen character salt prefixed with $5$. If the salt string starts with 'rounds=<N>$', the
numeric value of N is used to indicate how many times the hashing loop should be executed, much like the cost parameter on
Blowfish. The default number of rounds is 5000, there is a minimum of 1000 and a maximum of 999,999,999. Any selection
of N outside this range will be truncated to the nearest limit.
CRYPT_SHA512 - SHA-512 hash with a sixteen character salt prefixed with $6$. If the salt string starts with 'rounds=<N>$', the
numeric value of N is used to indicate how many times the hashing loop should be executed, much like the cost parameter on
Blowfish. The default number of rounds is 5000, there is a minimum of 1000 and a maximum of 999,999,999. Any selection
of N outside this range will be truncated to the nearest limit.
Parameters ¶
string
Caution
Using the CRYPT_BLOWFISH algorithm, will result in the string parameter being truncated to a maximum length of 72 bytes.
salt
A salt string to base the hashing on. If not provided, the behaviour is defined by the algorithm implementation and can lead to
unexpected results.
Return Values ¶
Returns the hashed string or a string that is shorter than 13 characters and is guaranteed to differ from the salt on failure.
Warning
When validating passwords, a string comparison function that isn't vulnerable to timing attacks should be used to compare the
output of crypt() to the previously known hash. PHP provides hash_equals() for this purpose.
Changelog ¶
Version Description
8.0.0 The salt is no longer optional.
Examples ¶
<?php
$user_input = 'rasmuslerdorf';
$hashed_password =
'$6$rounds=1000000$NJy4rIPjpOaU$0ACEYGg/aKCY3v8O8AfyiO7CTfZQ8/W231Qfh2tRLmfdvFD6XfHk12u6hMr9cYIA4hnpjLNSTRtUwYr9km9Ij/';
// Validate an existing crypt() hash in a way that is compatible with non-PHP software.
if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
echo "Password verified!";
}
?>
Notes ¶
Note: There is no decrypt function, since crypt() uses a one-way algorithm.
See Also ¶
Found A Problem?
Learn How To Improve This Page • Submit a Pull Request • Report a Bug
+add a note
up
down
70
bob dot orr at mailinator dot com ¶
10 years ago
The #2 comment on this comments page (as of Feb 2015) is 9 years old and recommends phpass. I have independently
security audited this product and, while it continues to be recommended for password security, it is actually insecure
and should NOT be used. It hasn't seen any updates in years (still at v0.3) and there are more recent alternatives
such as using the newer built-in PHP password_hash() function that are much better. Everyone, please take a few
moments to confirm what I'm saying is accurate (i.e. review the phpass code for yourself) and then click the down
arrow to sink the phpass comment to the bottom. You'll be increasing security across the Internet by doing so.
For those who want details: md5() with microtime() are a fallback position within the source code of phpass. Instead
of terminating, it continues to execute code. The author's intentions of trying to work everywhere are admirable but,
when it comes to application security, that stance actually backfires. The only correct answer in a security context
is to terminate the application rather than fallback to a weak position that can potentially be exploited (usually by
forcing that weaker position to happen).
up
down
34
Marten Jacobs ¶
11 years ago
As I understand it, blowfish is generally seen a secure hashing algorithm, even for enterprise use (correct me if I'm
wrong). Because of this, I created functions to create and check secure password hashes using this algorithm, and
using the (also deemed cryptographically secure) openssl_random_pseudo_bytes function to generate the salt.
<?php
/*
* Generate a secure hash for a given password. The cost is passed
* to the blowfish algorithm. Check the PHP manual page for crypt to
* find more information about this setting.
*/
function generate_hash($password, $cost=11){
/* To generate the salt, first generate enough random bytes. Because
* base64 returns one character for each 6 bits, the we should generate
* at least 22*6/8=16.5 bytes, so we generate 17. Then we get the first
* 22 base64 characters
*/
$salt=substr(base64_encode(openssl_random_pseudo_bytes(17)),0,22);
/* As blowfish takes a salt with the alphabet ./A-Za-z0-9 we have to
* replace any '+' in the base64 string with '.'. We don't have to do
* anything about the '=', as this only occurs when the b64 string is
* padded, which is always after the first 22 characters.
*/
$salt=str_replace("+",".",$salt);
/* Next, create a string that will be passed to crypt, containing all
* of the settings, separated by dollar signs
*/
$param='$'.implode('$',array(
"2y", //select the most secure version of blowfish (>=PHP 5.3.7)
str_pad($cost,2,"0",STR_PAD_LEFT), //add the cost in two digits
$salt //add the salt
));
/*
* Check the password against a hash generated by the generate_hash
* function.
*/
function validate_pw($password, $hash){
/* Regenerating the with an available hash as the options parameter should
* produce the same hash if the same password is passed.
*/
return crypt($password, $hash)==$hash;
}
?>
up
down
7
kaminski at istori dot com ¶
14 years ago
Here is an expression to generate pseudorandom salt for the CRYPT_BLOWFISH hash type:
The salt created will be 128 bits in length, padded to 132 bits and then expressed in 22 base64 characters.
(CRYPT_BLOWFISH only uses 128 bits for the salt, even though there are 132 bits in 22 base64 characters. If you
examine the CRYPT_BLOWFISH input and output, you can see that it ignores the last four bits on input, and sets them to
zero on output.)
Note that the high-order bits of the four 32-bit dwords returned by mt_rand() will always be zero (since mt_getrandmax
== 2^31), so only 124 of the 128 bits will be pseudorandom. I found that acceptable for my application.
up
down
6
steve at tobtu dot com ¶
12 years ago
To generate salt use mcrypt_create_iv() not mt_rand() because no matter how many times you call mt_rand() it will only
have at most 32 bits of entropy. Which you will start seeing salt collisions after about 2^16 users. mt_rand() is
seeded poorly so it should happen sooner.
For bcrypt this will actually generate a 128 bit salt:
<?php $salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.'); ?>
You don't need to do a full translate because they "round" to different characters:
echo crypt('', '$2y$05$.....................A') . "\n";
echo crypt('', '$2y$05$.....................Q') . "\n";
echo crypt('', '$2y$05$.....................g') . "\n";
echo crypt('', '$2y$05$.....................w') . "\n";
$2y$05$......................J2ihDv8vVf7QZ9BsaRrKyqs2tkn55Yq
$2y$05$.....................O/jw2XygQa2.LrIT7CFCBQowLowDP6Y.
$2y$05$.....................eDOx4wMcy7WU.kE21W6nJfdMimsBE3V6
$2y$05$.....................uMMcgjnOELIa6oydRivPkiMrBG8.aFp.
up
down
0
kevin dot nicasi at gmail dot com ¶
26 days ago
Most (old) examples here show how to generate a salt. But it's better to use the password_hash(...) function for this.
This is mentioned in the 3th paragraph ("Use of password_hash() is encouraged."). password_hash(...) will
automatically generate a salt that's concatenated to the generated hash string.
The function password_verify(...) will automatically use the concatenated salt to compare the hashes. So there's no
need to generate a salt yourself at all.
up
down
0
remi at php dot net ¶
3 months ago
The crypt_gensalt function (from the xpass extension) makes usage of this function much easier, ex:
<?php
<?php
$user_input = '12+#æ345';
$pass = urlencode($user_input));
$pass_crypt = crypt($pass);
String Functions
addcslashes
addslashes
bin2hex
chop
chr
chunk_split
convert_uudecode
convert_uuencode
count_chars
crc32
crypt
echo
explode
fprintf
get_html_translation_table
hebrev
hex2bin
html_entity_decode
htmlentities
htmlspecialchars
htmlspecialchars_decode
implode
join
lcfirst
levenshtein
localeconv
ltrim
md5
md5_file
metaphone
nl_langinfo
nl2br
number_format
ord
parse_str
print
printf
quoted_printable_decode
quoted_printable_encode
quotemeta
rtrim
setlocale
sha1
sha1_file
similar_text
soundex
sprintf
sscanf
str_contains
str_decrement
str_ends_with
str_getcsv
str_increment
str_ireplace
str_pad
str_repeat
str_replace
str_rot13
str_shuffle
str_split
str_starts_with
str_word_count
strcasecmp
strchr
strcmp
strcoll
strcspn
strip_tags
stripcslashes
stripos
stripslashes
stristr
strlen
strnatcasecmp
strnatcmp
strncasecmp
strncmp
strpbrk
strpos
strrchr
strrev
strripos
strrpos
strspn
strstr
strtok
strtolower
strtoupper
strtr
substr
substr_compare
substr_count
substr_replace
trim
ucfirst
ucwords
vfprintf
vprintf
vsprintf
wordwrap
Deprecated
convert_cyr_string
hebrevc
money_format
utf8_decode
utf8_encode
Search docs