Подтвердить что ты не робот

Шифрование и расшифровка строки JavaScript?

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

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

В идеале я мог бы сделать что-то вроде

var gibberish = encrypt(string, salt, key);

для генерации закодированной строки и что-то вроде

var sensical = decrypt(gibberish, key);

чтобы декодировать его позже.

До сих пор я видел это: http://bitwiseshiftleft.github.io/sjcl/

Любые другие библиотеки, на которые я должен смотреть?

4b9b3361

Ответ 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?

Во-первых, вам нужно решить одну вещь:

  1. Вы просто хотите зашифровать/расшифровать данные (и, возможно, все же каким-то образом безопасно использовать открытый текст в запросах к базе данных) и не беспокоиться о деталях? Или...
  2. Вам нужно реализовать определенный протокол?

Если вы выбрали первый вариант, получите 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