2013-06-06 2 views
6

Мне было интересно, можно ли хранить зашифрованное текстовое поле в моей базе данных и иметь возможность расшифровать этот фрагмент текста на основе соли и авторизованного пароля?Шифровать/расшифровать строку на основе солевого ключа

Например:

$Salt = $_POST['Salt']; 
$Password = $Query_Results['Password']; 

if ($salt == $Stored_Salt AND $Authorized_Password == $Password){ 
    //Perform a decryption of the stored results 
    echo $Decrypted_TextField; 
} 

Я нахожусь в процессе создания полностью зашифрованное/закодированный базы данных. Ничто не будет простым текстом, кроме целочисленных полей для идентификаторов. Все остальное будет зашифровано/закодировано. Многие будут использовать одностороннее шифрование, но некоторые поля должны содержать двоичный тип шифрования.

Я не могу разместить незашифрованный текст в базе данных. Перед хранением все необходимо зашифровать. Но подход к этому - неизвестный процесс для меня. Поэтому мне было интересно узнать, с чего начать:

+0

Поиск алгоритма симметричного шифрования AES – Patashu

+0

@Patashu Документация для расшифровки функций AES на php.net: http://www.php.net/manual/en/function.mcrypt-decrypt.php является недокументированной о том, как реально реализовать эти функции. Не могли бы вы пролить свет, если я получу успешную функцию шифрования? –

+0

Вы должны прочитать литературу о том, как работают симметричные функции шифрования и AES. Тогда все параметры этой функции будут очевидны. – Patashu

ответ

7

Похоже, что вы, возможно, захотите сделать еще какой-нибудь фон на крипто в целом, а также опции шифрования БД (вы не упомянули хранилище данных, но там являются параметрами MySQL и Postgres для полного шифрования). В общем, почти всегда плохая идея «сворачивать свои собственные», и, к сожалению, между функциями mcrypt() и openssl _ *() есть откровенно слишком много вариантов, представленных новичкам (например, представление EBC и CBC в равной степени действительные параметры). Хотя этот поток: https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own в основном говорит о тщетности создания «новых» криптографических примитивов, этот принцип также применяется к наивным попыткам внедрения шифрования на уровне приложений и баз данных.

Как практический вопрос, наиболее сложной задачей, с которой вам, вероятно, придется столкнуться, является проблема управления паролями/ключами. Приведенный ниже код ставит всю ответственность на клиента (отправителя) - и если вы не сохраните предоставленный пароль (какой вид поражения цели), если пользователь забывает или иным образом не может предоставить свой пароль в будущем, зашифрованные данные в базе данных будет unrecoverable. (И, да, если вы действительно хотите спуститься по пути Яковского бритья, есть варианты для шифрования с несколькими ключами).

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

Наконец, есть зрелая библиотека здесь: http://phpseclib.sourceforge.net/crypt/examples.html, но, на мой взгляд, она предлагает слишком много возможностей для начинающего пользователя (см., Например, режим EBC ​​по умолчанию в генераторе кода). Для пароль хеширования, внимательно ознакомьтесь с библиотекой phpPass здесь: http://www.openwall.com/phpass/.

Все, что сказано, представляет собой рабочий старт для простого двухстороннего, достаточно сильного шифрования со случайными генерируемыми векторами и солями инициализации и 256-битным AES-симметричным (например, не открытым ключом) шифрованием. Протестировано на OSX Lion & CentOS/RedHat 6.

Удачи!

//$message = escapeshellarg($_POST['message']); 
$message = 'This is my very secret data SSN# 009-68-1234'; 

// Set to some reasonable limit for DB. 
// Make sure to size DB column +60 chars 
$max_msg_size = 1000; 
$message = substr($message, 0, $max_msg_size); 

// User's password (swap for actual form post) 
//$password = escapeshellarg($_POST['password']); 
$password = 'opensesame'; 

// Salt to add entropy to users' supplied passwords 
// Make sure to add complexity/length requirements to users passwords! 
// Note: This does not need to be kept secret 
$salt = sha1(mt_rand()); 

// Initialization Vector, randomly generated and saved each time 
// Note: This does not need to be kept secret 
$iv = substr(sha1(mt_rand()), 0, 16); 

echo "\n Password: $password \n Message: $message \n Salt: $salt \n IV: $iv\n"; 

$encrypted = openssl_encrypt(
    "$message", 'aes-256-cbc', "$salt:$password", null, $iv 
); 

$msg_bundle = "$salt:$iv:$encrypted"; 
echo " Encrypted bundle = $msg_bundle \n\n "; 

// Save it... (make sure to use bind variables/prepared statements!) 
/* db_write("insert into sensitive_table encrypted_msg values (:msg_bundle)", 
    $msg_bundle); */ 

Теперь получить его: выход

// Retrieve from DB... 

//$password = escapeshellarg($_POST['password']); 
$password = 'opensesame'; 

// Swap with actual db retrieval code here 
//$saved_bundle = db_read("select encrypted_msg from sensitive_table"); 
$saved_bundle = $msg_bundle; 

// Parse iv and encrypted string segments 
$components = explode(':', $saved_bundle);; 

var_dump($components); 

$salt   = $components[0]; 
$iv   = $components[1]; 
$encrypted_msg = $components[2]; 

$decrypted_msg = openssl_decrypt(
    "$encrypted_msg", 'aes-256-cbc', "$salt:$password", null, $iv 
); 

if ($decrypted_msg === false) { 
    die("Unable to decrypt message! (check password) \n"); 
} 

$msg = substr($decrypted_msg, 41); 
echo "\n Decrypted message: $decrypted_msg \n"; 

Пример:

Password: opensesame 
Message: This is my very secret data SSN# 009-68-1234 

Salt: 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37 
IV: 00c1d3b4c6a6f4c3 

Encrypted bundle = 3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37:00c1d3b4c6a6f4c3:KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41 

array(3) { 
    [0]=> 
    string(40) "3f12ce187d5c5bcc3b0d5acf1e76fad8b684ff37" 
    [1]=> 
    string(16) "00c1d3b4c6a6f4c3" 
    [2]=> 
    string(64) "KB6k+GlM+0EHbETUgEe8Lck0nF5qBz+51wc5LtmS4XMOm0Pfyyr2PIXMVEyzs/41" 
} 

Decrypted message: This is my very secret data SSN# 009-68-1234 
2

Не полный ответ, но расширение как соление работ, что было слишком долго для комментариев ..

Соль не следует рассматривать как строку, которая должна быть com он должен быть частью пароля, который конечный пользователь не должен печатать, но является уникальным для этого пользователя. Он используется для предотвращения взлома одного взломанного пароля для нескольких учетных записей.

Например, допустим, у нас есть действительно простая система, на которой у Боба есть пароль ABCDEF.

Передача ABCDEF через наши результаты алгоритма хеширования в (скажем) ED6522687

Если злоумышленник получает доступ к списку паролей, они могут видеть только сохраненный хэш.

Конечно, если Джейн также использует тот же пароль, ее хэш также будет ED6522687 - это означает, что если вы перейдете на любую учетную запись (через грубую силу, социальную инженерию и т. Д.), Вы получите доступ до счета, так как вы можете видеть их хэши.

Salting - это то, что делается с паролем перед хэшированием, уникальным для каждого пользователя и повторяемым. Соль должна быть предсказуемой, так что скажем, соли Боба и Джейн являются случайными числами.

Теперь, если у вас есть пароль для bob ABCDEF123, вы получите другой хэш Jane's ABCDEF456.

Обратите внимание, что этот не является a полное объяснение. Некоторые другие вещи, чтобы рассмотреть следующие вопросы:

  • Там нет такого понятия, как случайное число в этом контексте, только криптографический безопасные случайные числа - и как случайные они сложно, связаны с энтропией и другими забавными вещами.
  • Как быстро вычисляется хеш, является важным фактором в отношении затруднения алгоритмов грубой форсировки - хеш, таких как bcrypt, которые рассчитаны на дорогостоящие вычисления. в отличие от (скажем) SHA2
  • Нет причин для того, чтобы пользователь представлял (или даже знал) свою соль.

Другое замечание, которое обычно недостаточно подчеркивается ... Вы не должны доверять никому, что вы читаете в Интернете, о такой теме - слишком много людей, которые имеют неполное понимание (я считаю себя среди них) , Поэтому принимайте это как причины не делать это самостоятельно, а не руководство о том, как это сделать.

Смежные вопросы