Как вы используете SHA256 для создания токена ключа, пары значений и секретной подписи? - PullRequest
4 голосов
/ 12 января 2012

Я хочу проверить некоторые скрытые поля ввода (чтобы убедиться, что они не изменены при отправке) с помощью sha-закодированной строки пар ключ-значение этих скрытых полей. Я видел примеры этого в Интернете, но я не понимал, как кодировать и декодировать значения с динамическим секретным значением. Может кто-нибудь помочь мне понять, как это сделать в Perl?

Кроме того, какой тип подписи (MD5, SHA1, SHA256 и т. Д.) Имеет хороший баланс производительности и безопасности?

обновление

Итак, как вы декодируете строку после ее кодирования?

Ответы [ 3 ]

3 голосов
/ 12 января 2012

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

Давайте разберемся в проблеме: вы визуализируете некоторые скрытые поля и хотите убедиться, чточто они представлены без изменений, верно?Вот как это можно сделать.

Предположим, у вас есть две переменные:

first: foo
second: bar

Вы можете хешировать их вместе с секретным ключом:

secret_key = "ysEJbKTuJU6u"
source_string = secret_key + "first" + "foo" + "second" + "bar"
hash = MD5(source_string)

# => "1adfda97d28af6535ef7e8fcb921d3f0"    

Теперь выможет отобразить вашу разметку:

<input type="hidden" name="first" value="foo" />
<input type="hidden" name="second" value="bar" />
<input type="hidden" name="hash" value="1adfda97d28af6535ef7e8fcb921d3f0">

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

Если хэши равны, ваши значения не изменились.

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

( отказ от ответственности: я не криптовалец, поэтому вы можете просто перестать читать сейчас )

Что касается производительности / безопасности, то, несмотря на то, что было обнаружено, что MD5 имеет слабость, он все еще довольно полезен, ИМХО.У SHA1 есть теоретическая слабость, хотя успешной атаки еще не было.В SHA-256 нет известных недостатков.

2 голосов
/ 13 января 2012

В действительности вам нужна не простая хеш-функция, а код аутентификации сообщения , например HMAC . Поскольку вы говорите, что хотите использовать SHA-256, вам может понравиться HMAC_SHA256, который доступен в Perl через модуль Digest :: SHA :

use Digest::SHA qw(hmac_sha256_base64);

my $mac = hmac_sha256_base64( $string, $key );

Здесь $key - произвольный ключ, который вы должны хранить в секрете, а $string содержит данные, которые вы хотите подписать. Чтобы применить это к более сложной структуре данных (такой как хэш пар ключей и значений), сначала необходимо преобразовать ее в строку. Есть несколько способов сделать это; например, вы можете использовать Storable :

use Storable qw(freeze);

sub pairs_to_string {
    local $Storable::canonical = 1;
    my %hash = @_;
    return freeze( \%hash );
}

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

Затем, перед отправкой данных пользователю, вы рассчитываете MAC для них и включаете его в качестве дополнительного поля в данные. Когда вы получаете данные обратно, вы удаляете поле MAC (и сохраняете его значение), пересчитываете MAC для оставшихся полей и сравниваете его с полученным значением. Если они не совпадают, кто-то (или что-то) подделал данные. Как это:

my $key = "secret";
sub mac { hmac_sha256_base64( pairs_to_string(@_), $key ) }

# before sending data to client:
my %data = (foo => "something", bar => "whatever");
$data{mac} = mac( %data );

# after receiving %data back from client:
my $mac = delete $data{mac};
die "MAC mismatch" if $mac ne mac( %data );

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

2 голосов
/ 12 января 2012

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

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

Итак, скажем, вы выбрали MD5, секрет JS90320ERHe2 и у вас есть следующие поля:

first_name = Jack
last_name = Smith
other_field = 7=2

Сначала URL кодирует его:

first_name=Jack&last_name=Smith&other_field=7%3d=2

Затем вычисляет хэш MD5

JS90320ERHe2first_name=Jack&last_name=Smith&other_field=7%3d=2

, равный 6d0fa69703935efaa183be57f81d38ea.Последнее закодированное поле:

first_name=Jack&last_name=Smith&other_field=7%3d=2&hash=6d0fa69703935efaa183be57f81d38ea

Так вот, что вы передаете пользователю.Чтобы проверить его, удалите хеш с конца, вычислите хеш MD5, объединив то, что осталось с секретом, и, если хэши совпадают, поле не было изменено.

Никто не может вычислить свой собственный действительныйMD5, потому что они не знают префикс строки с.

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

...