Существующие ответы, в которых используются SJCL, CryptoJS и / или WebCrypto, не обязательно ошибочны, но они не так безопасны, как вы могли изначально подозревать. Как правило, вы хотите использовать libsodium . Сначала я объясню почему, а затем как.
Почему не SJCL, CryptoJS, WebCrypto и т. Д.?
Краткий ответ: для того, чтобы ваше шифрование было действительно безопасным, эти библиотеки ожидают, что вы сделаете слишком много вариантов, например, режим блочного шифра (CBC, CTR, GCM; если вы не можете сказать, какой из трех перечисленных мною безопасен для использовать и при каких ограничениях вы не должны быть обременены таким выбором вообще ).
Если ваша должность не является инженером-криптографистом , вероятность того, что она будет надежно реализована, зависит от вас.
Зачем избегать CryptoJS?
CryptoJS предлагает несколько строительных блоков и ожидает, что вы знаете, как их безопасно использовать. Это даже по умолчанию в режиме CBC (в архиве ).
Почему режим CBC плох?
Прочтите эту статью об уязвимостях AES-CBC .
Зачем избегать WebCrypto?
WebCrypto - это стандарт безопасности, разработанный комитетом для целей, которые ортогональны разработке криптографии. В частности, WebCrypto должен был заменить Flash, а не обеспечивать безопасность .
Зачем избегать SJCL?
Публичный API и документация SJCL просят пользователей зашифровать данные с помощью запоминаемого человеком пароля. Это редко, если вообще, то, что вы хотите делать в реальном мире.
Дополнительно: стандартное количество раундов PBKDF2 по умолчанию примерно в 86 раз меньше, чем вы хотите . AES-128-CCM, вероятно, в порядке.
Из трех приведенных выше вариантов SJCL наименее вероятно закончится слезами. Но есть и лучшие варианты.
Почему Libsodium лучше?
Вам не нужно выбирать между меню режимов шифрования, хэш-функциями и другими ненужными опциями. Вы никогда не рискуете испортить ваши параметры и удалить всю безопасность из вашего протокола .
Вместо этого libsodium предлагает простые настройки, настроенные на максимальную безопасность и минималистичные API.
crypto_box()
/ crypto_box_open()
предложить аутентифицированное шифрование с открытым ключом.
- Рассматриваемый алгоритм объединяет X25519 (ECDH по Curve25519) и XSalsa20-Poly1305, но вам не нужно знать (или даже заботиться) об этом, чтобы использовать его безопасно
crypto_secretbox()
/ crypto_secretbox_open()
предложить шифрование с аутентификацией с общим ключом.
- Рассматриваемый алгоритм XSalsa20-Poly1305, но вам не нужно знать / заботиться
Кроме того, у libsodium есть привязки на десятках популярных языков программирования , поэтому очень вероятно, что libsodium просто сработает при попытке взаимодействия с другим стеком программирования. Кроме того, libsodium имеет тенденцию быть очень быстрым, не жертвуя безопасностью.
Как использовать Libsodium в JavaScript?
Во-первых, вам нужно решить одну вещь:
- Вы просто хотите зашифровать / расшифровать данные (и, возможно, все-таки как-то безопасно использовать открытый текст в запросах к базе данных) и не беспокоиться о деталях? Или...
- Вам нужно реализовать определенный протокол?
Если вы выбрали первый вариант , получите CipherSweet.js .
Документация доступна онлайн . EncryptedField
этого достаточно для большинства случаев использования, но API EncryptedRow
и EncryptedMultiRows
API могут быть проще, если у вас есть много различных полей, которые вы хотите зашифровать.
С CipherSweet вам даже не нужно знать, что такое nonce / IV, чтобы безопасно его использовать.
Кроме того, это обрабатывает int
/ float
шифрует без утечки фактов о содержимом через размер зашифрованного текста.
В противном случае вы захотите натрия-плюс , который является удобным интерфейсом для различных оболочек libsodium. Sodium-Plus позволяет писать производительный, асинхронный, кроссплатформенный код, который легко проверять и анализировать.
Чтобы установить натрий-плюс, просто запустите ...
npm install sodium-plus
В настоящее время нет общедоступной CDN для поддержки браузера. Это скоро изменится. Тем не менее, вы можете получить sodium-plus.min.js
из последней версии Github , если вам это нужно.
const { SodiumPlus } = require('sodium-plus');
let sodium;
(async function () {
if (!sodium) sodium = await SodiumPlus.auto();
let plaintext = 'Your message goes here';
let key = await sodium.crypto_secretbox_keygen();
let nonce = await sodium.randombytes_buf(24);
let ciphertext = await sodium.crypto_secretbox(
plaintext,
nonce,
key
);
console.log(ciphertext.toString('hex'));
let decrypted = await sodium.crypto_secretbox_open(
ciphertext,
nonce,
key
);
console.log(decrypted.toString());
})();
Документация для натрия-плюс доступна на Github.
Если вы хотите пошаговое руководство, эта статья содержит то, что вы ищете.