PHP 5.6.24 is released

crypt

(PHP 4, PHP 5, PHP 7)

cryptTek yönlü dizge şifrelemesi yapar

Açıklama

string crypt ( string $dizge [, string $tuz ] )

crypt() işlevi standart Unix DES şifreleme algoritmasını veya sistemdeki uygun algoritmalardan birini kullanarak dizge dizgesinin şifrelenmiş sürümünü döndürür.

Bazı işletim sistemleri birden fazla şifreleme türü destekler. Çoğunlukla da standart DES şifrelemesinin yerini MD5 şifreleme algoritması alır. Şifreleme türü tuz değiştirgesiyle tetiklenir. Tuz kabul edecek şifreleme türlerini ve işlevin yeteneklerini PHP kurulum sırasında saptar. tuz belirtilmemişse ve sistemin öntanımlı şifreleme türü MD5 ise rasgele bir MD5 uyumlu bir tuz üretilir; sistemin öntanımlı şifreleme türü MD5 değilse PHP öntanımlı olarak iki karakterlik tuz üretir. PHP, CRYPT_SALT_LENGTH sabitinde tuz uzunluğunu tanımlayarak, sistemde iki karakterlik mi yoksa daha uzun bir tuz mu (en fazla 20) kullanıldığını belirtir.

Standart DES şifrelemesinde crypt() işlevi tuz olarak çıktının ilk iki karakterini döndürür. Ayrıca, dizgenin sadece ilk sekiz karakterini kullanır, bu nedenle ilk sekiz karakteri aynı olan sekiz karakterden daha uzun dizgeler için tuz aynı olduğu sürece hep aynı sonucu üretir.

İşlevin çok sayıda şifreleme algoritması ile desteklendiği sistemlerde aşağıdaki sabitler desteklenen şifreleme türüne göre 0 veya 1 değerini alırlar:

  • CRYPT_STD_DES - İki karakterlik tuz kullanan standart DES şifrelemesi.
  • CRYPT_EXT_DES - Dokuz karakterlik tuz kullanan gelişkin DES şifrelemesi.
  • CRYPT_MD5 - $1$ ile başlayan on iki karakterlik MD5 şifrelemesi.
  • CRYPT_BLOWFISH - $2$ veya $2a$ ile başlayan on altı karakterlik Blowfish şifrelemesi.

Bilginize:

PHP 5.3.0 ve sonrasında, PHP kendi gerçeklenimini içerir ve sistemde desteği bulunmayan algoritmalar için bu gerçeklenimi kullanır.

Değiştirgeler

dizge

Şifrelenecek dizge.

tuz

Şifrelemeye göre değişen isteğe bağlı tuz dizgesi. Belirtilmediği takdirde PHP, işlevin her çağrılışında rasgele bir tane üretir.

Eğer kendi tuzunuzu kullanacaksanız işlevi çağırmadan önce üretmiş olmalısınız. İşlevi tekrar takrar çağırdığınız durumlarda bunun hem görünürde hem de güvenlikte bazı etkileri olur.

Dönen Değerler

Şifrelenmiş dizge.

Sürüm Bilgisi

Sürüm: Açıklama
5.3.0 PHP artık MD5, standart DES, gelişkin DES ve Blowfish şifreleme algoritmaları için kendi gerçeklenimini içeriyor ve sistemde bu algoritmalardan bulunmayanların yerine bu algoritmaları kullanıyor.

Örnekler

Örnek 1 - crypt() örnekleri

<?php
$parola 
crypt('parolam'); // Tuzu PHP üretsin

/* Parola karşılaştırmasında, farklı şifreleme algoritmaları ile ilgili
   sorunlardan kaçınmak için crypt() sonucunun tamamını tuz olarak işleve
   aktarmalısınız. (Yukarıda belirtildiği gibi standart DES parola özetleri
   2 karakterlik tuz kullanırken MD5 parola özetleri 12 karakterlik tuz
   kullanır.) */
if (crypt($kullanıcı _girdisi$parola) == $parola) {
   echo 
"Parola doğru!";
}
?>

Örnek 2 - htpasswd ile crypt() kullanımı

<?php
// Parolayı tanmılayalım
$parola 'parolam';

// Tuzu PHP üretsin ve bize parola özetini versin
$hash crypt($parola);
?>

Örnek 3 - crypt() işlevinin farklı şifreleme türleri ile kullanımı

<?php
if (CRYPT_STD_DES == 1) {
    echo 
'Standart DES: ' crypt('rasmuslerdorf''rl') . "\n";
}

if (
CRYPT_EXT_DES == 1) {
    echo 
'Gelişkin DES: ' crypt('rasmuslerdorf''_J9..rasm') . "\n";
}

if (
CRYPT_MD5 == 1) {
    echo 
'MD5:          ' crypt('rasmuslerdorf''$1$rasmusle$') . "\n";
}

if (
CRYPT_BLOWFISH == 1) {
    echo 
'Blowfish:     ' crypt('rasmuslerdorf',
            
'$2a$07$usesomesillystringforsalt$') . "\n";
}
?>

Yukarıdaki örnek şuna benzer bir çıktı üretir:

Standart DES: rl.3StKT.4T8M
Gelişkin DES: _J9..rasmBYk8r9AiWNc
MD5:          $1$rasmusle$rISCgZzpwk3UhDidwXvin0
Blowfish:     $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

Notlar

Bilginize: crypt() tek yönlü algoritma kullandığından tekrar özgün dizgeyi elde etmenizi sağlayacak bir işlev yoktur.

Ayrıca Bakınız

add a note add a note

User Contributed Notes 6 notes

up
22
bob dot orr at mailinator dot com
1 year 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
14
Marten Jacobs
2 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
       
));
      
       
//now do the actual hashing
       
return crypt($password,$param);
}

/*
* 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
8
steve at tobtu dot com
3 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)), '+', '.'); ?>

*** Bike shed ***
The last character in the 22 character salt is 2 bits.
base64_encode() will have these four character "AQgw"
bcrypt will have these four character ".Oeu"

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
7
jette at nerdgirl dot dk
3 years ago
The crypt() function cant handle plus signs correctly. So if for example you are using crypt in a login function, use urlencode on the password first to make sure that the login procedure can handle any character:

<?php
$user_input
'12+#æ345';
$pass = urlencode($user_input));
$pass_crypt = crypt($pass);

if (
$pass_crypt == crypt($pass, $pass_crypt)) {
  echo
"Success! Valid password";
} else {
  echo
"Invalid password";
}
?>
up
3
ian+php dot net at eiloart dot ocm
2 years ago
If you're stuck with CRYPT_EXT_DES, then you'll want to pick a number of iterations: the 2nd-5th characters of the "salt".

My experimentation suggests that the 5th character is the most significant. A '.' is a zero and 'Z' is the highest value. Using all dots will create an error: all passwords will be encrypted to the same value.

Here are some encryption timings (in seconds) that I obtained, with five different iteration counts over the same salt, and the same password, on a quad core 2.66GHz Intel Xeon machine.

_1111 time: 0.15666794776917
_J9.Z time: 1.8860530853271
_J9.. time: 0.00015401840209961
_...Z time: 1.9095730781555
_ZZZZ time: 1.9124970436096
_...A time: 0.61211705207825

I think a half a second is reasonable for an application, but for the back end authentication? I'm not so sure: there's a significant risk of overloading the back end if we're getting lots of authentication requests.
up
5
kaminski at istori dot com
5 years ago
Here is an expression to generate pseudorandom salt for the CRYPT_BLOWFISH hash type:

<?php $salt = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22); ?>

It is intended for use on systems where mt_getrandmax() == 2147483647.

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.
To Top