Принципиальная разница между алгоритмами хеширования и шифрования - PullRequest
483 голосов
/ 09 февраля 2011

Я вижу много путаницы между хэшами и алгоритмами шифрования, и мне хотелось бы услышать еще несколько советов экспертов о:

  1. Когда использовать хеши против шифрования

  2. Что отличает алгоритм хеширования или шифрования (от теоретического / математического уровня) то есть то, что делает хеши необратимыми (без помощи радуги)

Вот несколько похожих ТАК вопросов, которые не вдавались в подробности, которые я искал:

В чем разница между обфускацией, хэшированием и шифрованием?
Разница между шифрованием и хэшированием

Ответы [ 12 ]

704 голосов
/ 09 февраля 2011

Ну, вы можете посмотреть это в Википедии ... Но, так как вам нужно объяснение, я сделаю все возможное здесь:

Хеш-функции

Они обеспечивают отображение между входом произвольной длины и выходом (обычно) фиксированной длины (или меньшей длины). Это может быть что угодно, от простого crc32, до полноценной криптографической хеш-функции, такой как MD5 или SHA1 / 2/256/512. Дело в том, что происходит одностороннее картирование. Это всегда отображение много: 1 (то есть всегда будут конфликты), поскольку каждая функция выдает меньший вывод, чем она может вводить (если вы подадите каждый возможный файл 1 МБ в MD5, вы получите тонну коллизий).

Причина, по которой их трудно (или практически невозможно) изменить, заключается в том, как они работают внутри. Большинство криптографических хеш-функций многократно повторяют входной набор для получения выходных данных. Поэтому, если мы посмотрим на каждый блок ввода фиксированной длины (который зависит от алгоритма), хеш-функция вызовет это текущее состояние. Затем он будет перебирать состояние, менять его на новое и использовать его в качестве обратной связи для себя (MD5 делает это 64 раза для каждого 512-битного блока данных). Затем он каким-то образом объединяет результирующие состояния всех этих итераций вместе, чтобы сформировать результирующий хеш.

Теперь, если вы хотите декодировать хеш, вам сначала нужно выяснить, как разбить данный хеш на его повторяющиеся состояния (1 возможность для входных данных, меньших, чем размер фрагмента данных, многие для больших входных данных ). Тогда вам нужно будет отменить итерацию для каждого состояния. Теперь, чтобы объяснить, почему это ОЧЕНЬ сложно, представьте себе попытку вывести a и b из следующей формулы: 10 = a + b. Есть 10 положительных комбинаций a и b, которые могут работать. Теперь зациклитесь на этом несколько раз: tmp = a + b; a = b; b = tmp. За 64 итерации у вас будет более 10 ^ 64 возможностей. И это просто простое дополнение, в котором сохраняется состояние от итерации к итерации. Реальные хеш-функции выполняют намного больше одной операции (MD5 выполняет около 15 операций с 4 переменными состояния). А поскольку следующая итерация зависит от состояния предыдущей, а предыдущая уничтожается при создании текущего состояния, практически невозможно определить входное состояние, которое привело к заданному выходному состоянию (для каждой итерации не меньше). Объедините это с большим количеством задействованных возможностей, и для декодирования даже MD5 потребуется почти бесконечное (но не бесконечное) количество ресурсов. Так много ресурсов, что на самом деле значительно дешевле взломать хэш, если у вас есть представление о размере входных данных (для меньших входных данных), чем даже пытаться декодировать хэш.

Функции шифрования

Они обеспечивают отображение 1: 1 между входом и выходом произвольной длины. И они всегда обратимы. Важно отметить, что это обратимо, используя некоторый метод. И это всегда 1: 1 для данного ключа. Теперь существует несколько пар ввода: ключей, которые могут генерировать один и тот же вывод (фактически, в зависимости от функции шифрования они обычно есть). Хорошие зашифрованные данные неотличимы от случайного шума. Это отличается от хорошего вывода хеша, который всегда имеет согласованный формат.

Варианты использования

Используйте хеш-функцию, когда вы хотите сравнить значение, но не можете сохранить простое представление (по любому количеству причин). Пароли должны очень хорошо подходить к этому варианту использования, так как вы не хотите хранить их в виде текста по соображениям безопасности (и не должны). Но что, если вы хотите проверить файловую систему на наличие пиратских музыкальных файлов? Было бы непрактично хранить 3 МБ на музыкальный файл. Поэтому вместо этого возьмите хеш файла и сохраните его (md5 будет хранить 16 байтов вместо 3 МБ). Таким образом, вы просто хэшируете каждый файл и сравниваете его с сохраненной базой данных хэшей (на практике это не так хорошо работает из-за перекодирования, изменения заголовков файлов и т. Д., Но это пример использования).

Используйте хеш-функцию при проверке достоверности входных данных.Вот для чего они предназначены.Если у вас есть 2 элемента ввода и вы хотите проверить, одинаковы ли они, запустите оба с помощью хеш-функции.Вероятность столкновения астрономически мала для небольших входных размеров (при условии хорошей хэш-функции).Вот почему это рекомендуется для паролей.Для паролей длиной до 32 символов у md5 в 4 раза больше свободного пространства.SHA1 имеет 6-кратное выходное пространство (приблизительно).SHA512 имеет примерно в 16 раз больше места на выходе.Тебя не волнует, какой пароль был , тебя волнует, совпадает ли он с тем, который был сохранен.Вот почему вы должны использовать хеши для паролей.

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

Хеш-функции также отлично подходят для подписывания данных.Например, если вы используете HMAC, вы подписываете часть данных, беря хеш данных, объединенных с известным, но не переданным значением (секретным значением).Итак, вы отправляете простой текст и хэш HMAC.Затем получатель просто хэширует представленные данные с известным значением и проверяет, соответствует ли он переданному HMAC.Если это то же самое, вы знаете, что это не было подделано стороной без секретной ценности.Это обычно используется в защищенных системах cookie в каркасах HTTP, а также при передаче сообщений данных по HTTP, где требуется некоторая уверенность в целостности данных.

Замечание о хешах для паролей:

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

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

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

var hash = password + salt;
for (var i = 0; i < 5000; i++) {
    hash = sha512(hash + password + salt);
}

Существуют и другие, более стандартные реализации, такие как PBKDF2 , BCrypt .Но этот метод используется довольно многими системами, связанными с безопасностью (такими как PGP, WPA, Apache и OpenSSL).

Итог, hash(password) недостаточно хорош.hash(password + salt) лучше, но все же недостаточно хорошо ... Используйте механизм растянутых хэшей для создания хэшей паролей ...

Еще одно замечание о тривиальном растяжении

Не подпри любых обстоятельствах вывод одного хеша напрямую возвращается в хеш-функцию :

hash = sha512(password + salt); 
for (i = 0; i < 1000; i++) {
    hash = sha512(hash); // <-- Do NOT do this!
}

Причина этого связана с столкновениями.Помните, что все хеш-функции имеют коллизии, потому что возможное выходное пространство (количество возможных выходных данных) меньше, чем входное пространство.Чтобы понять почему, давайте посмотрим, что происходит.Чтобы предварить это, давайте предположим, что вероятность столкновения составляет 0,001% от sha1() (на самом деле это намного меньше, но для демонстрационных целей).

hash1 = sha1(password + salt);

Теперь,hash1 имеет вероятность столкновения 0,001%.Но когда мы делаем следующие hash2 = sha1(hash1);, , все коллизии hash1 автоматически становятся коллизиями hash2.Итак, теперь у нас есть коэффициент hash1 на уровне 0,001%, и второй вызов sha1() добавляет к этому.Так что теперь hash2 имеет вероятность столкновения 0,002%.Это в два раза больше шансов!Каждая итерация добавит еще один 0.001% шанс столкновения к результату.Таким образом, при 1000 итерациях вероятность столкновения подскочила с тривиального до 0,001% до 1%.Теперь ухудшение линейно, и реальные вероятности намного меньше, но эффект тот же (оценка вероятности одного столкновения с md5 составляет около 1 / (2 128 ) или 1 / (3x10 38 ). Хотя это кажется небольшим, благодаря празднованию дня рождения на самом деле это не так мало, как кажется).

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

hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
    hash = sha512(hash + password + salt);
}

Имеет такую ​​же вероятность столкновения, как и нативная функция sha512.Что ты хочешь?Используйте это вместо этого.

156 голосов
/ 09 февраля 2011

Хеш-функция может рассматриваться как выпечка буханки хлеба. Вы начинаете с входных данных (мука, вода, дрожжи и т. Д.), А после применения хэш-функции (смешивание + выпечка) вы получаете результат: буханка хлеба.

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

Множество различных вариантов входов теоретически будут давать идентичные буханки (например, 2 чашки воды и 1 цбп дрожжей дают точно такой же хлеб, как 2,1 стакана воды и 0,9 цбп дрожжей), но, учитывая один из этих хлебов, вы можете не скажи точно, какое сочетание входов произвело это.

Шифрование, с другой стороны, может рассматриваться как сейф. Все, что вы положили туда, возвращается, пока у вас есть ключ, с помощью которого он был заперт в первую очередь. Это симметричная операция. При наличии ключа и некоторого ввода вы получите определенный вывод. Учитывая этот вывод и тот же ключ, вы получите исходный ввод. Это отображение 1: 1.

42 голосов
/ 09 февраля 2011

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

Хеши берут некоторый ввод и превращают его в несколько бит (обычно это число, например 32-битное целое, 64-битное целое и т. Д.). Один и тот же ввод всегда будет давать один и тот же хеш, но вы ПРИНЦИПНО теряете информацию в процессе, поэтому вы не можете надежно воспроизвести исходный ввод (однако есть несколько предостережений).

Шифрование главным образом сохраняет всю информацию, которую вы вводите в функцию шифрования, просто затрудняет (в идеале невозможное) возвращение к исходному вводу без специального ключа.

Простой пример хеширования

Вот тривиальный пример, который поможет вам понять, почему хеширование не может (в общем случае) вернуть исходный ввод. Скажем, я создаю 1-битный хэш. Моя хэш-функция принимает строку битов в качестве входных данных и устанавливает хэш на 1, если во входной строке задано четное число битов, или 0, если было нечетное число.

Пример:

Input    Hash
0010     0
0011     1
0110     1
1000     0

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

Кстати, этот 1-битный хэш не совсем придуман ... взгляните на бит четности .

Простой пример шифрования

Вы можете зашифровать текст с помощью простой подстановки букв, скажем, если ввод A, вы пишете B. Если ввод B, вы пишете C. До конца алфавита, где, если ввод Z, ты пишешь снова А.

Input   Encrypted
CAT     DBU
ZOO     APP

Как и в простом хэш-примере, этот тип шифрования исторически использовался .

36 голосов
/ 07 апреля 2012

Базовый обзор методов хеширования и шифрования / дешифрования:

Хеширование:

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

hashing


Шифрование и дешифрование:

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

encryption and decryption


ОБНОВЛЕНИЕ: Для решения вопросов, упомянутых в отредактированном вопросе.

1.Когда использовать хеши против шифрования

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

Шифрование хорошо, если вы говорите, что хотите отправить кому-то сообщение.Вы шифруете сообщение ключом, а получатель дешифрует тем же (или, возможно, даже другим) ключом, чтобы вернуть исходное сообщение. кредитов


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

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

Шифрование / дешифрование (обратимое):

Сложение :

4 + 3 = 7  

Это можно поменять местами, взяв сумму и вычтя одно из добавлений

7 - 3 = 4     

Умножение:

4 * 5 = 20  

Это можно изменить, взяв произведение и разделив на один из факторов

20 / 4 = 5    

Итак, здесь можно предположить, что одно из добавлений / факторовключ расшифровки и результат (7,20) - это зашифрованный текст.


Хеширование (необратимое):

Деление по модулю :

22 % 7 = 1   

Это не может быть отменено, потому что нет операции, которую вы можете сделать с частным и дивидендом для восстановления делителя (или наоборот).

Можете ли вы найти операцию для заполнения, где '?'является?

1  ?  7 = 22  
1  ?  22 = 7

Таким образом, хеш-функции имеют то же математическое качество, что и деление по модулю, и теряют информацию.

кредиты

25 голосов
/ 29 января 2013

Мой единственный лайнер ... как правило, интервьюер хотел получить ответ ниже.

Хеширование - это один из способов. Вы не можете преобразовать ваши данные / строку из хеш-кода.

Шифрование - это 2 способа - вы можете снова расшифровать зашифрованную строку, если у вас есть ключ.

15 голосов
/ 10 апреля 2014

A Хеш-функция превращает объем текста переменного размера в текст фиксированного размера.

Hash

Источник: https://en.wikipedia.org/wiki/Hash_function

Позволяет увидеть это в действии.Я использую php для этого.

HASH:

$str = 'My age is 29';
$hash = hash('sha1', $str);
echo $hash; // OUTPUT: 4d675d9fbefc74a38c89e005f9d776c75d92623e

DEHASH:

SHA1 - односторонний хеш.Что означает, что вы не можете дешифровать хеш.Тем не менее, вы можете перебрать хэш.Пожалуйста, смотрите: https://hashkiller.co.uk/sha1-decrypter.aspx.

MD5, это еще один хеш.На этом сайте можно найти дэшер MD5: https://www.md5online.org/.


Функция шифрования преобразует текст в бессмысленный зашифрованный текст с помощью ключа шифрования и наоборот.enter image description here

Источник: https://en.wikipedia.org/wiki/Encryption

Давайте углубимся в некоторый код PHP, который обрабатывает шифрование.

--- Расширение Mcrypt ---

ENCRYPT:

$cipher = MCRYPT_RIJNDAEL_128;
$key = 'A_KEY';
$data = 'My age is 29';
$mode = MCRYPT_MODE_ECB;

$encryptedData = mcrypt_encrypt($cipher, $key , $data , $mode);
var_dump($encryptedData);

//OUTPUT:
string '„Ùòyªq³¿ì¼üÀpå' (length=16)

DECRYPT:

$decryptedData = mcrypt_decrypt($cipher, $key , $encryptedData, $mode);
$decryptedData = rtrim($decryptedData, "\0\4"); // Remove the nulls and EOTs at the END
var_dump($decryptedData);

//OUTPUT:
string 'My age is 29' (length=12)

--- Расширение OpenSSL --

Расширение Mcrypt устарело в версии 7.1.и удалены в php 7.2.Расширение OpenSSL должно использоваться в php 7. См. Фрагменты кода ниже:

$key = 'A_KEY';
$data = 'My age is 29';

// ENCRYPT
$encryptedData = openssl_encrypt($data , 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($encryptedData);

// DECRYPT    
$decryptedData = openssl_decrypt($encryptedData, 'AES-128-CBC', $key, 0, 'IV_init_vector01');
var_dump($decryptedData);

//OUTPUT
string '4RJ8+18YkEd7Xk+tAMLz5Q==' (length=24)
string 'My age is 29' (length=12)
9 голосов
/ 03 июля 2016

Симметричное шифрование:

Симметричное шифрование также может называться общим ключом или общим секретным шифрованием.При симметричном шифровании для шифрования и дешифрования трафика используется один ключ.

enter image description here

Асимметричное шифрование:

Асимметричное шифрование также известно как криптография с открытым ключом.Асимметричное шифрование отличается от симметричного шифрования прежде всего тем, что используются два ключа: один для шифрования и один для дешифрования.Наиболее распространенным алгоритмом асимметричного шифрования является RSA.

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

enter image description here

Хеширование:

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

enter image description here

Подробнее здесь: http://packetlife.net/blog/2010/nov/23/symmetric-asymmetric-encryption-hashing/

4 голосов
/ 09 февраля 2011

Алгоритмы шифрования и хеширования работают аналогично.В каждом случае необходимо создать путаницу и диффузию среди битов. confusion создает сложные отношения между ключом и зашифрованным текстом, а diffusion распространяет информацию о каждом бите.

Многие хеш-функции фактически используюталгоритмы шифрования (или примитивы алгоритмов шифрования. Например, кандидат SHA-3 Skein использует Threefish в качестве базового метода для обработки каждого блока. Разница в том, что вместо сохранения каждого блока зашифрованного текста, они разрушительно, детерминистически слитые вместе до фиксированной длины

4 голосов
/ 09 февраля 2011

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

когда дело доходит до авторизации, вы используете хеширование. В хешировании нет ключа

Хеширование берет любой объем данных (двоичный или текстовый) и создает хэш постоянной длины, представляющий контрольную сумму для данных. Например, хеш может быть 16 байтов. Различные алгоритмы хеширования производят хэши разного размера. Очевидно, что вы не можете заново создать исходные данные из хэша, но вы можете снова хэшировать данные, чтобы увидеть, генерируется ли то же самое значение хэша. Так работают односторонние пароли на основе Unix. Пароль хранится в виде значения хэша, и для входа в систему вводимый вами пароль хэшируется, и значение хэша сравнивается с хэшем реального пароля. Если они совпадают, значит, вы ввели правильный пароль

почему хеширование необратимо:

Хеширование необратимо, поскольку отображение ввода в хэш не равно 1: 1. Наличие двух входов, отображаемых на одно и то же значение хеша, обычно называется «коллизией хешей». В целях безопасности одно из свойств «хорошей» хеш-функции заключается в том, что при практическом использовании коллизии встречаются редко.

4 голосов
/ 09 февраля 2011
  1. Используйте хэши, когда вам нужно идти только в одну сторону.Например, для паролей в системе вы используете хеширование, потому что вы всегда будете проверять, чтобы значение, введенное пользователем после хеширования, соответствовало значению в вашем хранилище.С шифрованием вы можете пойти двумя путями.

  2. алгоритмы хеширования и алгоритмы шифрования - это всего лишь математические алгоритмы.Так что в этом отношении они ничем не отличаются - это всего лишь математические формулы.Однако в отношении семантики существует очень большое различие между хешированием (односторонним) и шифрованием (двусторонним).Почему хеши необратимы?Потому что они разработаны таким образом, потому что иногда вам нужна односторонняя операция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...