Существуют ли какие-либо реализации SHA-256 javascript, которые обычно считаются надежными?


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

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

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

7   51   2013-08-19 21:15:47

7 ответов:

The Stanford JS Crypto Library содержит реализацию SHA-256. Хотя криптография в JS на самом деле не так хорошо проверена, как другие платформы реализации, эта, по крайней мере, частично разработана и в определенной степени спонсируется,Dan Boneh, который является хорошо зарекомендовавшим себя и надежным именем в криптографии, и означает, что проект имеет некоторый надзор со стороны кого-то, кто действительно знает, что он делает. Проект также поддерживается NSF.

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

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

Forgeреализация SHA-256 является быстрым и надежным.

чтобы выполнить тесты на нескольких реализациях SHA-256 JavaScript, перейдите к http://brillout.github.io/test-javascript-hash-implementations/.

результаты на моей машине предполагают, что forge является самой быстрой реализацией, а также значительно быстрее, чем Криптобиблиотека Stanford Javascript (sjcl), упомянутая в принятом ответе.

Forge-это 256 КБ, но извлечение кода, связанного с SHA-256, уменьшает размер до 4,5 КБ, см. https://github.com/brillout/forge-sha256

нет, нет никакого способа использовать браузер JavaScript для улучшения безопасности паролей. Я настоятельно рекомендую вам прочитать в этой статье. В вашем случае самой большой проблемой является проблема куриного яйца:

в чем" проблема куриного яйца " с доставкой криптографии Javascript?

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

[...]

почему я не могу использовать TLS/SSL для доставки криптокода Javascript?

вы можете. Это сложнее, чем кажется, но вы безопасно передаете JavaScript crypto в браузер с помощью SSL. Проблема в том, что, установив безопасный канал с SSL, вам больше не нужна криптография Javascript; у вас есть " реальный" криптография.

что приводит к этому:

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

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

в основном проблема заключается в следующем:

  • ваши клиенты не доверяют свои сервера, поэтому они хотят добавить дополнительный код безопасности.
  • этот код безопасности поставляется вашими серверами (те, которым они не доверяют).

или

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

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

Я нашел эту реализацию очень простой в использовании. Также имеет щедрую лицензию в стиле BSD:

jsSHA:https://github.com/Caligatio/jsSHA

Мне нужен был быстрый способ получить шестнадцатеричное представление хэша SHA-256. Прошло всего 3 строки:

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");

On https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest я нашел этот фрагмент, который использует внутренний модуль js:

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder('utf-8').encode(message);                    

    // hash the message
    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);

    // convert ArrayBuffer to Array
    const hashArray = Array.from(new Uint8Array(hashBuffer));

    // convert bytes to hex string                  
    const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
    return hashHex;
}

для тех, кто заинтересован, это код для создания SHA-256 хэш с помощью sjcl:

import sjcl from 'sjcl'

const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)

кроме Стэнфордской библиотеки, о которой упоминал тайлерл. Я нашел jsrsasign очень полезно (GitHub РЕПО здесь:https://github.com/kjur/jsrsasign). я не знаю, насколько точно он заслуживает доверия, но я использовал его API SHA256, Base64, RSA, x509 и т. д. и это работает довольно хорошо. На самом деле, он также включает в себя Стэнфордский lib.

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