Шифрование и расшифровка строки JavaScript?
Мне интересно создать небольшое приложение для личного использования, которое будет шифровать и расшифровывать информацию на стороне клиента с помощью JavaScript. Зашифрованная информация будет храниться в базе данных на сервере, но не в расшифрованной версии.
Он не должен быть супер-пупер безопасным, но я бы хотел использовать текущий непрерывный алгоритм.
В идеале я мог бы сделать что-то вроде
var gibberish = encrypt(string, salt, key);
для генерации закодированной строки и что-то вроде
var sensical = decrypt(gibberish, key);
чтобы декодировать его позже.
До сих пор я видел это:
http://bitwiseshiftleft.github.io/sjcl/
Любые другие библиотеки, на которые я должен смотреть?
Ответы
Ответ 1
var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
//U2FsdGVkX18ZUVvShFSES21qHsQEqZXMxQ9zgHy+bu0=
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
//4d657373616765
document.getElementById("demo1").innerHTML = encrypted;
document.getElementById("demo2").innerHTML = decrypted;
document.getElementById("demo3").innerHTML = decrypted.toString(CryptoJS.enc.Utf8);
Full working sample actually is:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<br><br>
<label>encrypted</label>
<div id="demo1"></div>
<br>
<label>decrypted</label>
<div id="demo2"></div>
<br>
<label>Actual Message</label>
<div id="demo3"></div>
Ответ 2
Как насчет CryptoJS?
Это надежная крипто библиотека, с большим количеством функциональных возможностей. Он реализует хэши, HMAC, PBKDF2 и шифры. В этом случае шифры - это то, что вам нужно. Проверьте быстрый старт на домашней странице проекта.
Вы могли бы сделать что-то вроде с AES:
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
var encryptedAES = CryptoJS.AES.encrypt("Message", "My Secret Passphrase");
var decryptedBytes = CryptoJS.AES.decrypt(encryptedAES, "My Secret Passphrase");
var plaintext = decryptedBytes.toString(CryptoJS.enc.Utf8);
</script>
Что касается безопасности, то на момент написания моей статьи алгоритм AES считается непрерывным
Редактировать :
Похоже, что онлайн-адрес не работает, и вы можете использовать загруженные файлы для шифрования по указанной ниже ссылке и поместить соответствующие файлы в корневую папку приложения.
https://code.google.com/archive/p/crypto-js/downloads
или использовал другой CDN, например https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/aes-min.js
Ответ 3
Я создал простой текстовый шифр/расшифровщик утилит. Нет зависимостей с какой-либо внешней библиотекой.
Это функции
let cipher = salt => {
let textToChars = text => text.split('').map(c => c.charCodeAt(0))
let byteHex = n => ("0" + Number(n).toString(16)).substr(-2)
let applySaltToChar = code => textToChars(salt).reduce((a,b) => a ^ b, code)
return text => text.split('')
.map(textToChars)
.map(applySaltToChar)
.map(byteHex)
.join('')
}
let decipher = salt => {
let textToChars = text => text.split('').map(c => c.charCodeAt(0))
let saltChars = textToChars(salt)
let applySaltToChar = code => textToChars(salt).reduce((a,b) => a ^ b, code)
return encoded => encoded.match(/.{1,2}/g)
.map(hex => parseInt(hex, 16))
.map(applySaltToChar)
.map(charCode => String.fromCharCode(charCode))
.join('')
}
И вы можете использовать их следующим образом:
// To create a cipher
let myCipher = cipher('mySecretSalt')
//Then cipher any text:
myCipher('the secret string') // --> "7c606d287b6d6b7a6d7c287b7c7a61666f"
//To decipher, you need to create a decipher and use it:
let myDecipher = decipher('mySecretSalt')
myDecipher("7c606d287b6d6b7a6d7c287b7c7a61666f") // --> 'the secret string'
Ответ 4
Современные браузеры теперь поддерживают API-интерфейс crypto.subtle
, который предоставляет собственные функции шифрования и дешифрования (не менее асинхронно!) С использованием одного из следующих методов: AES-CBC, AES-CTR, AES-GCM или RSA-OAEP.
https://www.w3.org/TR/WebCryptoAPI/#dfn-Crypto
Ответ 5
Существующие ответы, в которых используются 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
могут быть проще, если у вас есть много различных полей, которые вы хотите зашифровать.
С 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());
})();
Ответ 6
CryptoJS больше не поддерживается. Если вы хотите продолжить использовать его, вы можете переключиться на этот URL:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
Ответ 7
Используйте SimpleCrypto
Использование encrypt() и decrypt()
Чтобы использовать SimpleCrypto, сначала создайте экземпляр SimpleCrypto с секретным ключом (паролем). Параметр секретного ключа ДОЛЖЕН быть определен при создании экземпляра SimpleCrypto.
Чтобы зашифровать и расшифровать данные, просто используйте функции encrypt() и decrypt() из экземпляра. Это будет использовать алгоритм шифрования AES-CBC.
var _secretKey = "some-unique-key";
var simpleCrypto = new SimpleCrypto(_secretKey);
var plainText = "Hello World!";
var chiperText = simpleCrypto.encrypt(plainText);
console.log("Encryption process...");
console.log("Plain Text : " + plainText);
console.log("Cipher Text : " + cipherText);
var decipherText = simpleCrypto.decrypt(cipherText);
console.log("... and then decryption...");
console.log("Decipher Text : " + decipherText);
console.log("... done.");
Ответ 8
Простые функции,
function Encrypt(value)
{
var result="";
for(i=0;i<value.length;i++)
{
if(i<value.length-1)
{
result+=value.charCodeAt(i)+10;
result+="-";
}
else
{
result+=value.charCodeAt(i)+10;
}
}
return result;
}
function Decrypt(value)
{
var result="";
var array = value.split("-");
for(i=0;i<array.length;i++)
{
result+=String.fromCharCode(array[i]-10);
}
return result;
}
Ответ 9
Если вы создаете приложение реагирования или nodejs, вы можете просто использовать эту библиотеку ncrypt-js для шифрования и дешифрования ваших данных.
Смотрите пример для кодов и коробки
Использование:
ES5
var ncrypt = require('ncrypt-js'); // or var { encrypt, decrypt } = require('ncrypt-js);
let encryptData = ncrypt.encrypt('super secret data', 'secret_key');
// or
// let encryptData = encrypt('super secret data', 'secret_key');
console.log(encryptData); // 11ab949601eb136f58ac3fe846e30d76.f9ce133b20adc35eef32af95957547abbb6fbfc5cb91cd14f5b0a088bd031883963cde1a56fd62fe2aeb75451a065d21
var decryptedData = ncrypt.decrypt(encryptData);
// or
// var decryptedData = decrypt(encryptData);
console.log(decryptedData); // super secret data
ES6
import ncrypt from 'ncrypt-js'; // or import { encrypt, decrypt } from 'ncrypt-js';
const encryptData = ncrypt.encrypt('super secret data', 'secret_key');
// or
// const encryptData = encrypt('super secret data', 'secret_key');
console.log(encryptData); // 11ab949601eb136f58ac3fe846e30d76.f9ce133b20adc35eef32af95957547abbb6fbfc5cb91cd14f5b0a088bd031883963cde1a56fd62fe2aeb75451a065d21
const decryptedData = ncrypt.decrypt(encryptData);
// or
// const decryptedData = decrypt(encryptData);
console.log(decryptedData); // super secret data