2015-09-29 2 views
1

Я работаю над функцией javascript для шифрования и хранения паролей в браузере с использованием 6-значного PIN-кода. Хотя это может быть легко принудительно принудительно, код на стороне сервера предотвращает это, блокируя учетную запись после 3 неправильных попыток.Функция криптографии, которая всегда расшифровывает текст, даже с неправильным ключом

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

Может ли кто-нибудь порекомендовать криптографическую функцию/библиотеку javascript, которая всегда расшифровывает текст, даже с неправильным ключом?

var encrypted = CryptoJS.AES.encrypt("password:abcdefg", "pin:123456"); 
 
$('#1').text(encrypted); 
 

 

 
var decryptedCorrect = CryptoJS.AES.decrypt($('#1').text(), "pin:123456") 
 
$('#3').text(decryptedCorrect.toString(CryptoJS.enc.Utf8)); 
 

 
var decryptedInCorrect = CryptoJS.AES.decrypt($('#1').text(), "pin:112233") 
 
$('#4').text(decryptedInCorrect.toString(CryptoJS.enc.Utf8));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script> 
 

 
<div> 
 
    Encrypted text: <span id="1"></span> 
 
</div> 
 
<br /> 
 
<div> 
 
    Decrypted with correct pin: <span id="3"></span> 
 
</div> 
 
<br /> 
 
<div> 
 
    Decrypted with incorrect pin: <span id="4"></span> 
 
</div> 
 
(Ideally the above should be some plain text value)

+0

Что значит «всегда расшифровывается до простого текста»? Результатом любого дешифрования является простой текст по определению. Это не может быть * правильным * простым текстом, но это все равно, что это такое. – Pointy

+0

См. Пример кода выше, он возвращает пустое значение, когда это неправильный ключ. –

+1

Я могу видеть проблему, которую имел бы OP. Если злоумышленник попробует ПИН-код, и он ошибочен, он всегда будет выдавать некоторый байт, но эти байты будут с подавляющей вероятностью отображать байты, которые являются членами стандартного набора символов, если и только если правильный PIN-код правильный. Это особый вид оракула, и он быстро выдаст правильный ПИН. ОП, боюсь, я не могу придумать какой-либо сильный шифр, который сделает все, что вам нужно. Каждый из них, я знаю, выводит псевдослучайное распределение по всем 256 возможным выходам для данного байта и не ограничивается стандартными символами. – WDS

ответ

2

В целом, это не может работать.

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

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

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

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

Очевидно, что универсальный алгоритм шифрования не может этого сделать.


Итак, как может вам достичь что-то вроде того, что вы хотите? В принципе, у вас есть два варианта:

  1. Вы можете увеличить длину своих ключей, чтобы они не были практически перечислены. Если вы используете случайные десятичные числа (фактически выбранные случайным образом, а не пользователем!), Тогда примерно 25-30 цифр должны быть минимальной безопасной длиной.

    Вы можете сократить длину немного, используя key stretching.Например, если вы используете каждую клавишу 100 000 раз, прежде чем использовать результат для дешифрования данных, вы можете сократить размер вашего пространства в размере 100 000, то есть от 25 цифр до 20.

    Вы также можете сделать свои ключи проще запомнить, кодируя их как фразы. Например, вы можете составить список из 1000 коротких общих английских слов (или use an existing list) и заменить каждую группу из трех цифр в своем пароле соответствующим словом в списке. Для большинства людей намного проще запомнить, скажем, последовательность из пяти случайных слов, чем случайное 25-значное число.

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

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

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

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

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

1

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

Обратите внимание, что ваша случайная схема не заменяет TLS и может - и, вероятно, иметь - другие уязвимости.

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