====== PHP RFC: Change crypt() behavior w/o salt ====== * Version: 1.0 * Date: 2013-08-22 * Author: Yasuo Ohgaki ( yohgaki@ohgaki.net ) * Status: Accepted * First Published at: http://wiki.php.net/rfc/crypt_function_salt ===== Introduction ===== crypt() without "salt" parameter produces too weak password hash. However, many users are using crypt() without salt parameter. ===== Proposal ===== There are several options for this issue. - Make crypt() generates stronger salt and uses strong hash automatically. - Raise E_STRICT or E_NOTICE when salt is omitted. - Leave crypt() as it is now and warn users by document. ===== Backward Incompatible Changes ===== * Option 1 may generate backward incompatible hash. * Option 2 may break apps due to error. * Option 3 does not change crypt() and no issue. ===== Proposed PHP Version(s) ===== master branch ===== Proposed Voting Choices ===== Option 1 to 3. ===== Patches and Tests ===== Patch for option 1 is posted to internals ML by Platonides diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 113a5bd..7731808 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -98,8 +98,6 @@ #define PHP_STD_DES_CRYPT 1 #endif -#define PHP_CRYPT_RAND php_rand(TSRMLS_C) - PHP_MINIT_FUNCTION(crypt) /* {{{ */ { REGISTER_LONG_CONSTANT("CRYPT_SALT_LENGTH", PHP_MAX_SALT_LEN, CONST_CS | CONST_PERSISTENT); @@ -134,17 +132,6 @@ PHP_MSHUTDOWN_FUNCTION(crypt) /* {{{ */ } /* }}} */ -static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static void php_to64(char *s, long v, int n) /* {{{ */ -{ - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} -/* }}} */ - PHPAPI int php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, char **result) { char *crypt_res; @@ -278,11 +265,14 @@ PHP_FUNCTION(crypt) if (!*salt) { #if PHP_MD5_CRYPT strncpy(salt, "$1$", PHP_MAX_SALT_LEN); - php_to64(&salt[3], PHP_CRYPT_RAND, 4); - php_to64(&salt[7], PHP_CRYPT_RAND, 4); + if (php_password_make_salt(8, &salt[3] TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11); #elif PHP_STD_DES_CRYPT - php_to64(&salt[0], PHP_CRYPT_RAND, 2); + if (php_password_make_salt(2, &salt[0] TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } salt[2] = '\0'; #endif salt_in_len = strlen(salt); ===== Vote ===== The vote started on 24.09.2013 and ended on 01.10.2013. * Generate strong salt by default * Generate E_NOTICE error * Keep current behavior (Use weak hash) ===== References ===== * http://jp2.php.net/crypt * https://bugs.php.net/bug.php?id=55036