Лучший способ использовать PHP для шифрования и дешифрования паролей?

Возможный дубликат:
PHP 2-way encryption: мне нужно хранить пароли, которые можно получить

Я планирую хранить информацию о чужой учетной записи для своих пользователей на своем веб-сайте, например, имя пользователя и пароль rapidshare и т.д.... Я хочу сохранить информацию в безопасности, но я знаю, что если я передам их информацию, я не смогу ее получить для последующего использования.

Base64 способен расшифровывать, поэтому нет смысла использовать это просто. Моя идея состоит в том, чтобы скрестить пользователя и пройти до и после того, как он получит base64ed таким образом даже после того, как вы расшифруете его, вы получите какой-то забавный текст, если попытаетесь расшифровать. Есть ли php-функция, которая принимает значения, которые будут создавать уникальную скремблировку строки и дешифровать ее позже, когда значение будет заново наложено?

Любые предложения?

Ответ 1

Вы не должны шифровать пароли, вместо этого вы должны использовать их с помощью алгоритма, такого как bcrypt. В этом ответе объясняется, как правильно реализовать хеширование паролей в PHP. Тем не менее, вот как вы шифруете/расшифровываете:

$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces

Чтобы зашифровать:

$iv = mcrypt_create_iv(
    mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
    MCRYPT_DEV_URANDOM
);

$encrypted = base64_encode(
    $iv .
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        $string,
        MCRYPT_MODE_CBC,
        $iv
    )
);

Чтобы расшифровать:

$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

$decrypted = rtrim(
    mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
        MCRYPT_MODE_CBC,
        $iv
    ),
    "\0"
);

Предупреждение. В приведенном выше примере шифруется информация, но он не аутентифицирует зашифрованный текст для предотвращения несанкционированного доступа. Вы не должны полагаться на неаутентифицированное шифрование для обеспечения безопасности, тем более, что код, как предусмотрено, уязвим для атак наложения.

Смотрите также:

Кроме того, не просто используйте "пароль" для ключа шифрования. Ключами шифрования являются случайные строки.


Демо на 3v4l.org:

echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "

Ответ 2

Предупреждение о безопасности. Этот класс не является безопасным. Он использует Rijndael256-ECB, который не является семантически безопасным. Просто потому, что "он работает" не означает "он защищен". Кроме того, он впоследствии удаляет хвостохранилища из-за отсутствия правильного заполнения.

Недавно этот класс нашел, он работает как сон!

class Encryption {
    var $skey = "yourSecretKey"; // you can change it

    public  function safe_b64encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }

    public function safe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public  function encode($value){ 
        if(!$value){return false;}
        $text = $value;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
        return trim($this->safe_b64encode($crypttext)); 
    }

    public function decode($value){
        if(!$value){return false;}
        $crypttext = $this->safe_b64decode($value); 
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
        return trim($decrypttext);
    }
}

И чтобы называть его:

$str = "My secret String";

$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);    

echo "$encoded<p>$decoded";

Ответ 3

Предупреждение о безопасности: Этот код не защищен.

рабочий пример

define('SALT', 'whateveryouwant'); 

function encrypt($text) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

$encryptedmessage = encrypt("your message"); 
echo decrypt($encryptedmessage); 

Ответ 4

Одна вещь, о которой вам следует знать при работе с шифрованием:

Попытка быть умной и изобретать свою собственную вещь, как правило, оставит вас с чем-то небезопасным.

Вероятно, вам лучше всего использовать один из расширений криптографии, которые поставляются с PHP.

Ответ 5

Это даст вам предельную защиту. Если злоумышленник может запускать произвольный код в своем приложении, он может получить пароли точно так же, как это может сделать ваше приложение. Вы все равно можете получить некоторую защиту от некоторых атак SQL-инъекций и неулокальных резервных копий db, если вы храните секретный ключ в файле и используете их для шифрования на пути к db и расшифровки на выходе. Но вы должны использовать bindparams, чтобы полностью избежать проблемы с SQL-инъекцией.

Если вы решили зашифровать, для этого вам нужно использовать некоторую криптографическую библиотеку высокого уровня, иначе вы ошибетесь. Вам нужно будет проверить правильность настройки клавиатуры, сообщений и проверки целостности, или все ваши усилия по шифрованию малопригодны. GPGME является хорошим выбором для одного примера. Mcrypt слишком низкий уровень, и вы, вероятно, ошибетесь.

Ответ 6

Предупреждение Securiy. Этот код небезопасен. Помимо уязвимости для атак с выбранным шифротекстом, его зависимость от unserialize() делает его уязвимым для инъекции объектов PHP.

Для обработки строки/массива я использую эти две функции:

function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
 return $s;
}

function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
 return $s;
}

Он гибкий, поскольку вы можете хранить/отправлять по URL-адресу строку или массив, потому что строка/массив сериализуется до шифрования.

Ответ 7

Проверьте mycrypt(): http://us.php.net/manual/en/book.mcrypt.php

И если вы используете postgres, там pgcrypto для шифрования уровня базы данных. (упрощает поиск и сортировку)

Ответ 8

Лучшая идея для шифрования/дешифрования ваших данных в базе данных, даже если у вас есть доступ к коду, заключается в использовании двух разных проходов для частного пользователя (user-pass) для каждого пользователя и личного кода для всех пользователей (system-pass).

Сценарий

  • user-pass хранится с md5 в базе данных и используется для проверки каждого пользователя для входа в систему. Этот пользовательский проход отличается для каждого пользователя.
  • Каждая запись пользователя в базе данных имеет значение md5 a system-pass для шифрования/дешифрования данных. Этот системный пароль для каждого пользователя одинаковый.
  • В любое время, когда пользователь удаляется из системы, все данные, зашифрованные под старым системным пропуском, должны быть зашифрованы снова в соответствии с новым системным пропуском, чтобы избежать проблем с безопасностью.