Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Helpers /////////////////////////////////////////////
- // Taken from https://github.com/google/closure-library/blob/e877b1eac410c0d842bcda118689759512e0e26f/closure/goog/crypt/crypt.js
- // Apache Licensed
- stringToUtf8ByteArray = function(str) {
- // TODO(user): Use native implementations if/when available
- var out = [], p = 0;
- for (var i = 0; i < str.length; i++) {
- var c = str.charCodeAt(i);
- if (c < 128) {
- out[p++] = c;
- } else if (c < 2048) {
- out[p++] = (c >> 6) | 192;
- out[p++] = (c & 63) | 128;
- } else if (
- ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&
- ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
- // Surrogate Pair
- c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
- out[p++] = (c >> 18) | 240;
- out[p++] = ((c >> 12) & 63) | 128;
- out[p++] = ((c >> 6) & 63) | 128;
- out[p++] = (c & 63) | 128;
- } else {
- out[p++] = (c >> 12) | 224;
- out[p++] = ((c >> 6) & 63) | 128;
- out[p++] = (c & 63) | 128;
- }
- }
- return new Uint8Array(out);
- };
- // Taken from https://github.com/google/closure-library/blob/e877b1eac410c0d842bcda118689759512e0e26f/closure/goog/crypt/crypt.js
- // Apache Licensed
- utf8ByteArrayToString = function(bytes) {
- // TODO(user): Use native implementations if/when available
- let out = [], pos = 0, c = 0;
- while (pos < bytes.length) {
- let c1 = bytes[pos++];
- if (c1 < 128) {
- out[c++] = String.fromCharCode(c1);
- } else if (c1 > 191 && c1 < 224) {
- let c2 = bytes[pos++];
- out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
- } else if (c1 > 239 && c1 < 365) {
- // Surrogate Pair
- let c2 = bytes[pos++];
- let c3 = bytes[pos++];
- let c4 = bytes[pos++];
- let u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) -
- 0x10000;
- out[c++] = String.fromCharCode(0xD800 + (u >> 10));
- out[c++] = String.fromCharCode(0xDC00 + (u & 1023));
- } else {
- let c2 = bytes[pos++];
- let c3 = bytes[pos++];
- out[c++] =
- String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
- }
- }
- return out.join('');
- };
- function byteArrayToHexString(byteArray) {
- if (!byteArray) {
- return '';
- }
- var hexStr = '';
- for (var i = 0; i < byteArray.length; i++) {
- var hex = (byteArray[i] & 0xff).toString(16);
- hex = (hex.length === 1) ? '0' + hex : hex;
- hexStr += hex;
- }
- return hexStr.toUpperCase();
- }
- function hexStringToByteArray(hexString) {
- let result = new Uint8Array(hexString.length/2), i = 0;
- while (hexString.length >= 2) {
- result[i++] = parseInt(hexString.substring(0, 2), 16);
- hexString = hexString.substring(2, hexString.length);
- }
- return result;
- }
- // /////////////////////////////////////////////
- // Crypto /////////////////////////////////////////////
- // Uses Web Crypto API (SubtleCrypto)
- var _crypto = window.crypto || window.msCrypto;
- if (!_crypto)
- {
- alert("Cryptography API Not Supported.");
- throw 'Cryptography API Not Supported.';
- }
- var _algorithm = "AES-CBC";
- var _key_size = 256;
- var _pbkdf_iterations = 100;
- // Do not change this once used in production
- var _defaultSalt = "af95a2b25229d227269a54fdec562d93";
- // Generates a new Key
- function _generateKey()
- {
- // Extractable is set to false so that underlying key details cannot be accessed.
- return crypto.subtle.generateKey({name: _algorithm, length: _key_size}, false, ["encrypt", "decrypt"]);
- }
- // Derives a key from the given password.
- // Salt is not required. If supplied should be a hex string.
- function deriveKey(passphrase, salt)
- {
- if (typeof(salt) === 'undefined')
- {
- salt = _defaultSalt;
- }
- return passphrase == null || passphrase.length < 10 ?
- Promise.reject("Password must be at least 10 characters") :
- crypto.subtle.importKey(
- 'raw',
- stringToUtf8ByteArray(passphrase),
- { name: 'PBKDF2'},
- false,
- ['deriveBits', 'deriveKey' ]
- ).then(function(passwordKey) {
- return crypto.subtle.deriveKey(
- {
- "name": 'PBKDF2',
- "salt": hexStringToByteArray(salt),
- "iterations": _pbkdf_iterations,
- "hash": 'SHA-256'
- },
- passwordKey,
- { "name": _algorithm, "length": _key_size },
- false, // Extractable is set to false so that underlying key details cannot be accessed.
- [ "encrypt", "decrypt" ]
- );
- });
- }
- function encryptData(keyObject, data)
- {
- let iv = crypto.getRandomValues(new Uint8Array(16));
- return crypto.subtle.encrypt(
- {name: _algorithm, iv: iv},
- keyObject,
- data
- ).then(function(encryptedData) {
- return {
- iv:iv,
- data:encryptedData
- }
- });
- }
- function decryptData(keyObject, iv, encryptedData)
- {
- return crypto.subtle.decrypt(
- {name: _algorithm, iv: iv},
- keyObject,
- encryptedData
- );
- }
- // Usage /////////////////////////////////////////////
- var theKey= null;
- function fromPassword() {
- var password = prompt("Please enter key derivation password. This should be at least 10 characters - ideally random. Unicode is supported.");
- if (password !== null)
- {
- deriveKey(password)
- .then(function(keyObject) {
- theKey = keyObject;
- }).catch(function(err) {
- alert(err);
- });
- }
- };
- function encrypt_data() {
- var data = stringToUtf8ByteArray(document.getElementById('cleartext').value);
- encryptData(theKey, data).then(function(encryptedData) {
- document.getElementById('cleartext').value = "";
- document.getElementById('encrypted').value = byteArrayToHexString(new Uint8Array(encryptedData.data));
- document.getElementById('iv').value = byteArrayToHexString(encryptedData.iv);
- });
- };
- function decrypt_data() {
- var encryptedData = hexStringToByteArray(document.getElementById('encrypted').value);
- var iv_plain = document.getElementById('iv').value;
- var iv = hexStringToByteArray(document.getElementById('iv').value);
- document.getElementById('cleartext').value = "";
- decryptData(theKey, iv, encryptedData).then(function(data) {
- document.getElementById('cleartext').value = utf8ByteArrayToString(new Uint8Array(data));
- }).catch(function (err) {
- document.getElementById('cleartext').value = "[Error - Wrong Key?]: " + err;
- });
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement