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

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

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

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

Какие-либо предложения?

8 ответов

Решение

Вы не должны шифровать пароли, вместо этого вы должны хешировать их, используя алгоритм вроде 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 "

Предупреждение безопасности: этот класс не является безопасным. Он использует 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";

Предупреждение о безопасности: этот код не является безопасным.

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

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); 

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

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

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

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

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

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 строку или массив, потому что строка / массив сериализуется перед шифрованием.

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

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

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

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

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

сценарий

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