From 9951a259a46401a59ff9165241158373eef235b8 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Thu, 19 Sep 2013 20:04:26 +0200 Subject: [PATCH] removed copied files from crypto lib --- .gitignore | 10 +- src/js/crypto/aes-cbc.js | 91 --------- src/js/crypto/crypto-batch.js | 362 ---------------------------------- src/js/crypto/rsa.js | 140 ------------- src/js/crypto/util.js | 207 ------------------- 5 files changed, 7 insertions(+), 803 deletions(-) delete mode 100644 src/js/crypto/aes-cbc.js delete mode 100644 src/js/crypto/crypto-batch.js delete mode 100644 src/js/crypto/rsa.js delete mode 100644 src/js/crypto/util.js diff --git a/.gitignore b/.gitignore index 372dcd5..ad56970 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ -node_modules +node_modules/ npm-debug.log .DS_Store *-browserified.js test/new-unit/lib/ .sass-cache -src/css/style.css -dist/ \ No newline at end of file +dist/ +src/lib/*.js +src/js/crypto/aes-cbc.js +src/js/crypto/crypto-batch.js +src/js/crypto/rsa.js +src/js/crypto/util.js \ No newline at end of file diff --git a/src/js/crypto/aes-cbc.js b/src/js/crypto/aes-cbc.js deleted file mode 100644 index 999349c..0000000 --- a/src/js/crypto/aes-cbc.js +++ /dev/null @@ -1,91 +0,0 @@ -(function() { - 'use strict'; - - /** - * A Wrapper for Forge's AES-CBC encryption - */ - var AesCBC = function(forge) { - this._forge = forge; - }; - - /** - * Encrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256) - * @param plaintext [String] The input string in UTF-16 - * @param key [String] The base64 encoded key - * @param iv [String] The base64 encoded IV - * @return [String] The base64 encoded ciphertext - */ - AesCBC.prototype.encrypt = function(plaintext, key, iv) { - // validate args - if (!plaintext || !key || !iv) { - throw new Error("Missing args for encryption!"); - } - - // decode args to utf8 and encrypt - var cipher = this._forge.aes.createEncryptionCipher(this._forge.util.decode64(key)); - cipher.start(this._forge.util.decode64(iv)); - cipher.update(this._forge.util.createBuffer(this._forge.util.encodeUtf8(plaintext))); - cipher.finish(); - - // encode to base64 - return this._forge.util.encode64(cipher.output.getBytes()); - }; - - /** - * Decrypt a String using AES-CBC-Pkcs7 using the provided keysize (e.g. 128, 256) - * @param ciphertext [String] The base64 encoded ciphertext - * @param key [String] The base64 encoded key - * @param iv [String] The base64 encoded IV - * @return [String] The decrypted plaintext in UTF-16 - */ - AesCBC.prototype.decrypt = function(ciphertext, key, iv) { - // validate args - if (!ciphertext || !key || !iv) { - throw new Error("Missing args for decryption!"); - } - - // decode args input to utf8 decrypt - var cipher = this._forge.aes.createDecryptionCipher(this._forge.util.decode64(key)); - cipher.start(this._forge.util.decode64(iv)); - cipher.update(this._forge.util.createBuffer(this._forge.util.decode64(ciphertext))); - cipher.finish(); - - // decode to utf16 - return this._forge.util.decodeUtf8(cipher.output.getBytes()); - }; - - /** - * Calculate a hmac using SHA-256 for a given input - * @param parts [Array] Array of Base64 encoded parts - * @param key [String] The base64 encoded key - * @return [String] The Base64 encoded hmac - */ - AesCBC.prototype.hmac = function(parts, key) { - var self = this; - - // validate args - if (!parts || parts.length < 1 || !key) { - throw new Error("Missing args for hmac processing!"); - } - - var hmac = self._forge.hmac.create(); - hmac.start('sha256', self._forge.util.decode64(key)); - parts.forEach(function(i) { - // decode base64 part and append to hmac msg - hmac.update(self._forge.util.decode64(i)); - }); - - return self._forge.util.encode64(hmac.digest().getBytes()); - }; - - if (typeof define !== 'undefined' && define.amd) { - // AMD - define(['node-forge'], function(forge) { - return new AesCBC(forge); - }); - } else if (typeof module !== 'undefined' && module.exports) { - // node.js - module.exports = new AesCBC(require('node-forge')); - } - -})(); \ No newline at end of file diff --git a/src/js/crypto/crypto-batch.js b/src/js/crypto/crypto-batch.js deleted file mode 100644 index 77f4edb..0000000 --- a/src/js/crypto/crypto-batch.js +++ /dev/null @@ -1,362 +0,0 @@ -(function() { - 'use strict'; - - /** - * Crypto batch library for processing large sets of data - */ - var CryptoBatch = function(aes, rsa, util, _) { - this._aes = aes; - this._rsa = rsa; - this._util = util; - this.__ = _; - }; - - // - // Encrypt batch for user AES/RSA - // - - /** - * Encrypt and sign a list of items using AES and RSA - * @param list [Array] The list of items to encrypt - * @param receiverPubkeys [Array] A list of public keys used to encrypt - * @param senderPrivkey [Array] The sender's private key used to sign - */ - CryptoBatch.prototype.encryptListForUser = function(list, receiverPubkeys, senderPrivkey) { - var receiverPk, - self = this; - - // validate presence of args - if (!list || !receiverPubkeys || !senderPrivkey || !senderPrivkey._id || !senderPrivkey.privateKey) { - throw new Error('Arguments missing!'); - } - - // set sender private key - self._rsa.init(null, senderPrivkey.privateKey); - - // encrypt a list of items - self.encryptList(list); - - list.forEach(function(i) { - // fetch correct public key for encryption - receiverPk = null; - receiverPk = self.__.findWhere(receiverPubkeys, { - _id: i.receiverPk - }); - - // validate presence of args - if (!receiverPk || !receiverPk.publicKey || !i.key || !i.iv || !i.ciphertext) { - throw new Error('Arguments missing!'); - } - - // encrypt item for user - self.encryptItemKeyForUser(i, receiverPk.publicKey, senderPrivkey._id); - }); - - return list; - }; - - /** - * Encrypt and sign an item using AES and RSA - * @param i [Object] The item to encrypt - * @param receiverPubkey [String] The public key used to encrypt - * @param senderKeyId [String] The sender's private key ID used to sign - */ - CryptoBatch.prototype.encryptItemKeyForUser = function(i, receiverPubkey, senderKeyId) { - var self = this; - - // set rsa public key used to encrypt - self._rsa.init(receiverPubkey); - // encrypt symmetric item key for user - i.encryptedKey = self._rsa.encrypt(i.key); - // set sender's keypair id for later verification - i.senderPk = senderKeyId; - // sign the bundle - i.signature = self._rsa.sign([i.iv, i.key, i.ciphertext]); - - // delete plaintext values - delete i.key; - delete i.receiverPk; - - return i; - }; - - // - // Decrypt batch for user AES/RSA - // - - /** - * Decrypt and verify a list of items using AES and RSA - * @param list [Array] The list of items to decrypt - * @param senderPubkeys [Array] A list of public keys used to verify - * @param receiverPrivkey [Array] The receiver's private key used to decrypt - */ - CryptoBatch.prototype.decryptListForUser = function(list, senderPubkeys, receiverPrivkey) { - var j; - - // validate presence of args - if (!list || !senderPubkeys || !receiverPrivkey || !receiverPrivkey._id || !receiverPrivkey.privateKey) { - throw new Error('Arguments missing!'); - } - - // verify and decrypt a list of items using RSA - this.decryptListKeysForUser(list, senderPubkeys, receiverPrivkey); - - // decrypt a list of items - this.decryptList(list); - - // set plaintext as list item - for (j = 0; j < list.length; j++) { - list[j] = list[j].plaintext; - } - - return list; - }; - - /** - * Decrypt and verify a list of item keys using RSA - * @param list [Array] The list of items to decrypt - * @param senderPubkeys [Array] A list of public keys used to verify - * @param receiverPrivkey [String] The receiver's private key used to decrypt - */ - CryptoBatch.prototype.decryptListKeysForUser = function(list, senderPubkeys, receiverPrivkey) { - var self = this, - senderPk; - - // set receiver private key - self._rsa.init(null, receiverPrivkey.privateKey); - - list.forEach(function(i) { - // fetch correct public key for verification - senderPk = null; - senderPk = self.__.findWhere(senderPubkeys, { - _id: i.senderPk - }); - - // validate presence of args - if (!senderPk || !senderPk.publicKey || !i.encryptedKey || !i.iv || !i.ciphertext) { - throw new Error('Arguments missing!'); - } - - // decrypt item for user - self.decryptItemKeyForUser(i, senderPk.publicKey); - }); - - return list; - }; - - /** - * Verfiy an item and decrypt its item key using RSA - * @param i [Object] The item to decrypt - * @param senderPubkey [String] A public key used to verify - */ - CryptoBatch.prototype.decryptItemKeyForUser = function(i, senderPubkey) { - var self = this; - - // set rsa public key used to verify - self._rsa.init(senderPubkey); - - // decrypt symmetric item key for user - i.key = self._rsa.decrypt(i.encryptedKey); - - // verify signature - if (!self._rsa.verify([i.iv, i.key, i.ciphertext], i.signature)) { - throw new Error('Verifying RSA signature failed!'); - } - - // delete ciphertext values - delete i.signature; - delete i.encryptedKey; - delete i.senderPk; - - return i; - }; - - // - // Encrypt batch AES - // - - /** - * Encrypt an item using AES - * @param i [Object] The item to encrypt - */ - CryptoBatch.prototype.encryptItem = function(i) { - var self = this; - - // stringify to JSON before symmetric encryption - i.ciphertext = self._aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv); - - // delete plaintext values - delete i.plaintext; - - return i; - }; - - /** - * Encrypt a list of items using AES - * @param i [Object] The item to encrypt - */ - CryptoBatch.prototype.encryptList = function(list) { - var self = this; - - list.forEach(function(i) { - // encrypt item - self.encryptItem(i); - }); - - return list; - }; - - /** - * Encrypt a list of items using AES and hash using HMAC - * @param i [Object] The item to encrypt - */ - CryptoBatch.prototype.authEncryptList = function(list) { - var self = this; - - self.encryptList(list); - - list.forEach(function(i) { - // calculate hmac of iv and ciphertext using key - i.hmac = self._aes.hmac([i.iv, i.ciphertext], i.key); - - // delete symmetric key on each item - delete i.key; - }); - - return list; - }; - - // - // Decrypt batch AES - // - - /** - * Decrypt an item using AES - * @param i [Object] The item to decrypt - */ - CryptoBatch.prototype.decryptItem = function(i) { - var self = this; - - // symmetrically decrypt JSON and parse to object literal - i.plaintext = JSON.parse(self._aes.decrypt(i.ciphertext, i.key, i.iv)); - - // delete ciphertext values - delete i.ciphertext; - - return i; - }; - - /** - * Decrypt a list of items using AES - * @param i [Object] The item to decrypt - */ - CryptoBatch.prototype.decryptList = function(list) { - var self = this; - - list.forEach(function(i) { - // decrypt item - self.decryptItem(i); - }); - - return list; - }; - - /** - * Encrypt a list of items using AES and verfiy using HMAC - * @param i [Object] The item to decrypt - */ - CryptoBatch.prototype.authDecryptList = function(list, keys) { - var self = this, - i, len, calculated, j; - - for (i = 0, len = list.length; i < len; i++) { - // validate presence of args - if (!list[i].hmac || !list[i].iv || !list[i].ciphertext || !keys[i]) { - throw new Error('Arguments for hmac verification missing!'); - } - - // verify hmac of each item - calculated = self._aes.hmac([list[i].iv, list[i].ciphertext], keys[i]); - if (list[i].hmac !== calculated) { - throw new Error('Hmac verification failed!'); - } - - // set key property for batch decryption - list[i].key = keys[i]; - } - - // decrypt lsit using aes - self.decryptList(list); - - // set plaintext as list item - for (j = 0; j < list.length; j++) { - list[j] = list[j].plaintext; - } - - return list; - }; - - // - // Reencrypt batch for user AES/RSA - // - - /** - * Decrypt a list of item keys using RSA and the encrypt them again using AES - * @param list [Array] The list of items to decrypt - * @param senderPubkeys [Array] A list of public keys used to verify - * @param receiverPrivkey [String] The receiver's private key used to decrypt - * @param symKey [String] The symmetric key used to re-encrypt the item key - */ - CryptoBatch.prototype.reencryptListKeysForUser = function(list, senderPubkeys, receiverPrivkey, symKey) { - var self = this; - - // verify and decrypt item keys using RSA - this.decryptListKeysForUser(list, senderPubkeys, receiverPrivkey); - - list.forEach(function(i) { - // re-encrypt item key using aes - i.encryptedKey = self._aes.encrypt(i.key, symKey, i.iv); - - delete i.key; - }); - - return list; - }; - - /** - * Decrypt keys and items using AES - * @param list [Array] The list of items to decrypt - * @param symKey [String] The symmetric key used to re-encrypt the item key - */ - CryptoBatch.prototype.decryptKeysAndList = function(list, symKey) { - var self = this, - j; - - list.forEach(function(i) { - // decrypt item key - i.key = self._aes.decrypt(i.encryptedKey, symKey, i.iv); - // decrypt item for user - self.decryptItem(i); - - delete i.encryptedKey; - }); - - // set plaintext as list item - for (j = 0; j < list.length; j++) { - list[j] = list[j].plaintext; - } - - return list; - }; - - if (typeof define !== 'undefined' && define.amd) { - // AMD - define(['cryptoLib/aes-cbc', 'cryptoLib/rsa', 'cryptoLib/util', 'underscore'], function(aes, rsa, util, _) { - return new CryptoBatch(aes, rsa, util, _); - }); - } else if (typeof module !== 'undefined' && module.exports) { - // node.js - module.exports = new CryptoBatch(require('./aes-cbc'), require('./rsa'), require('./util'), require('underscore')); - } - -})(); \ No newline at end of file diff --git a/src/js/crypto/rsa.js b/src/js/crypto/rsa.js deleted file mode 100644 index cc31f65..0000000 --- a/src/js/crypto/rsa.js +++ /dev/null @@ -1,140 +0,0 @@ -(function() { - 'use strict'; - - /** - * A Wrapper for Forge's RSA encryption - */ - var RSA = function(forge, util, app) { - - var utl = forge.util; - - var keypair = {}; - - /** - * Initializes the RSA module by passing the user's keypair - * The private key is option and required only for decryption - * and signing - */ - this.init = function(pubkeyPem, privkeyPem, keyId) { - if (pubkeyPem) { - keypair.publicKey = forge.pki.publicKeyFromPem(pubkeyPem); - } - if (privkeyPem) { - keypair.privateKey = forge.pki.privateKeyFromPem(privkeyPem); - } - if (keyId) { - keypair._id = keyId; - } - }; - - /** - * Generate RSA keypair with the corresponding keysize - */ - this.generateKeypair = function(keySize, callback) { - forge.rsa.generateKeyPair({ - bits: keySize, - workerScript: (typeof app !== 'undefined') ? (app.config.workerPath + '/../lib/prime.worker.js') : undefined - }, function(err, newKeypair) { - if (err || !newKeypair || !newKeypair.publicKey || !newKeypair.privateKey) { - callback({ - errMsg: 'RSA keygeneration failed!', - err: err - }); - return; - } - - keypair = newKeypair; - // generate unique keypair ID - keypair._id = util.UUID(); - - callback(null, { - _id: keypair._id, - pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey), - privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey) - }); - }); - }; - - /** - * Exports user's keypair as PEMs - */ - this.exportKeys = function() { - return { - _id: keypair._id, - pubkeyPem: forge.pki.publicKeyToPem(keypair.publicKey), - privkeyPem: forge.pki.privateKeyToPem(keypair.privateKey) - }; - }; - - /** - * Encrypt a String using RSA with PKCS#1 v1.5 padding - * @param plaintext [String] The input string in UTF-16 - * @return [String] The base64 encoded ciphertext - */ - this.encrypt = function(plaintext) { - // encode plaintext to utf8 and encrypt - var ct = keypair.publicKey.encrypt(utl.encodeUtf8(plaintext)); - // encode ciphtext to base64 - return utl.encode64(ct); - }; - - /** - * Decrypt a String using RSA with PKCS#1 v1.5 padding - * @param ciphertext [String] The base64 encoded ciphertext - * @return [String] The decrypted plaintext in UTF-16 - */ - this.decrypt = function(ciphertext) { - // decode base64 ciphertext to utf8 - var ctUtf8 = utl.decode64(ciphertext); - // decrypt and decode to utf16 - return utl.decodeUtf8(keypair.privateKey.decrypt(ctUtf8)); - }; - - /** - * Signs an Array of Base64 encoded parts with the private key - * @param parts [Array] Array of Base64 encoded parts - * @return [String] The Base64 encoded signature - */ - this.sign = function(parts) { - var sha = forge.md.sha256.create(); - parts.forEach(function(i) { - // decode base64 part and append to sha msg - sha.update(utl.decode64(i)); - }); - - // encode signature to base64 - return utl.encode64(keypair.privateKey.sign(sha)); - }; - - /** - * Verifies an Array of Base64 encoded parts with the public key - * @param parts [Array] Array of Base64 encoded parts - * @param sig [String] The Base64 encoded signatrure - * @return [bool] if the verification was successful - */ - this.verify = function(parts, sig) { - // decode base64 signature to utf8 - var sigUtf8 = utl.decode64(sig); - - var sha = forge.md.sha256.create(); - parts.forEach(function(i) { - // decode base64 part and append to sha msg - sha.update(utl.decode64(i)); - }); - - return keypair.publicKey.verify(sha.digest().getBytes(), sigUtf8); - }; - - }; - - if (typeof define !== 'undefined' && define.amd) { - // AMD - define(['node-forge', 'cryptoLib/util', 'js/app-config'], function(forge, util, app) { - return new RSA(forge, util, app); - }); - } else if (typeof module !== 'undefined' && module.exports) { - // node.js - module.exports = new RSA(require('node-forge'), require('./util')); - } - -})(); \ No newline at end of file diff --git a/src/js/crypto/util.js b/src/js/crypto/util.js deleted file mode 100644 index 2ccb9a5..0000000 --- a/src/js/crypto/util.js +++ /dev/null @@ -1,207 +0,0 @@ -(function() { - 'use strict'; - - /** - * Various utitity methods for crypto, encoding & decoding - */ - var Util = function(forge, uuid, crypt) { - this._forge = forge; - this._uuid = uuid; - this._crypt = crypt; - }; - - /** - * Generates a new RFC 4122 version 4 compliant random UUID - */ - Util.prototype.UUID = function() { - return this._uuid.v4(); - }; - - /** - * Generates a cryptographically secure random base64-encoded key or IV - * @param keySize [Number] The size of the key in bits (e.g. 128, 256) - * @return [String] The base64 encoded key/IV - */ - Util.prototype.random = function(keySize) { - var keyBase64, keyBuf; - - if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) { - // browser if secure rng exists - keyBuf = new Uint8Array(keySize / 8); - window.crypto.getRandomValues(keyBuf); - keyBase64 = window.btoa(this.uint8Arr2BinStr(keyBuf)); - } else if (typeof module !== 'undefined' && module.exports) { - // node.js - keyBuf = this._crypt.randomBytes(keySize / 8); - keyBase64 = new Buffer(keyBuf).toString('base64'); - } else { - // generate random bytes with fortuna algorithm from forge - keyBase64 = window.btoa(this._forge.random.getBytesSync(keySize / 8)); - } - - return keyBase64; - }; - - /** - * Parse a date string with the following format "1900-01-31 18:17:53" - */ - Util.prototype.parseDate = function(str) { - var parts = str.match(/(\d+)/g); - return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]); - }; - - /** - * Returns a string representation of a date in the format "1900-01-31 18:17:53" - */ - Util.prototype.formatDate = function(date) { - var year = "" + date.getFullYear(); - var month = "" + (date.getMonth() + 1); - if (month.length === 1) { - month = "0" + month; - } - var day = "" + date.getDate(); - if (day.length === 1) { - day = "0" + day; - } - var hour = "" + date.getHours(); - if (hour.length === 1) { - hour = "0" + hour; - } - var minute = "" + date.getMinutes(); - if (minute.length === 1) { - minute = "0" + minute; - } - var second = "" + date.getSeconds(); - if (second.length === 1) { - second = "0" + second; - } - return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second; - }; - - /** - * Converts a binary String (e.g. from the FileReader Api) to an ArrayBuffer - * @param str [String] a binary string with integer values (0..255) per character - * @return [ArrayBuffer] - */ - Util.prototype.binStr2ArrBuf = function(str) { - var b = new ArrayBuffer(str.length); - var buf = new Uint8Array(b); - - for (var i = 0, len = b.byteLength; i < len; i++) { - buf[i] = str.charCodeAt(i); - } - - return b; - }; - - /** - * Converts an ArrayBuffer to a binary String. This is a slower alternative to - * conversion with arrBuf2Blob -> blob2BinStr, since these use native apis, - * but it can be used on browsers without the BlodBuilder Api - * @param buf [ArrayBuffer] - * @return [String] a binary string with integer values (0..255) per character - */ - Util.prototype.arrBuf2BinStr = function(buf) { - var b = new Uint8Array(buf); - var str = ''; - - for (var i = 0, len = b.length; i < len; i++) { - str += String.fromCharCode(b[i]); - } - - return str; - }; - - /** - * Converts a UInt8Array to a binary String. - * @param buf [UInt8Array] - * @return [String] a binary string with integer values (0..255) per character - */ - Util.prototype.uint8Arr2BinStr = function(buf) { - var str = ''; - - for (var i = 0, len = buf.length; i < len; i++) { - str += String.fromCharCode(buf[i]); - } - - return str; - }; - - /** - * Converts a binary String (e.g. from the FileReader Api) to a UInt8Array - * @param str [String] a binary string with integer values (0..255) per character - * @return [UInt8Array] - */ - Util.prototype.binStr2Uint8Arr = function(str) { - var c, buf = new Uint8Array(str.length); - - for (var i = 0, len = buf.length; i < len; i++) { - c = str.charCodeAt(i); - buf[i] = (c & 0xff); - } - - return buf; - }; - - /** - * Convert a str to base64 in a browser and in node.js - */ - Util.prototype.str2Base64 = function(str) { - if (typeof window !== 'undefined' && window.btoa) { - return window.btoa(str); - } else if (typeof module !== 'undefined' && module.exports) { - return new Buffer(str, 'binary').toString('base64'); - } else { - return this._forge.util.encode64(str); - } - }; - - /** - * Convert a base64 encoded string in a browser and in node.js - */ - Util.prototype.base642Str = function(str) { - if (typeof window !== 'undefined' && window.atob) { - return window.atob(str); - } else if (typeof module !== 'undefined' && module.exports) { - return new Buffer(str, 'base64').toString('binary'); - } else { - return this._forge.util.decode64(str); - } - }; - - /** - * Convert a UTF-16 encoded string to UTF8 - * @param str [String] a UTF-16 encoded string - */ - Util.prototype.encodeUtf8 = function(str) { - return this._forge.util.encodeUtf8(str); - }; - - /** - * Convert a UTF-8 encoded string to UTF-16 - * @param str [String] a UTF-8 encoded string - */ - Util.prototype.decodeUtf8 = function(str) { - return this._forge.util.decodeUtf8(str); - }; - - /** - * Validate an email address. This regex is taken from: - * http://stackoverflow.com/questions/46155/validate-email-address-in-javascript - */ - Util.prototype.validateEmailAddress = function(emailAddress) { - var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(emailAddress); - }; - - if (typeof define !== 'undefined' && define.amd) { - // AMD - define(['uuid', 'node-forge'], function(uuid, forge) { - return new Util(forge, uuid, undefined); - }); - } else if (typeof module !== 'undefined' && module.exports) { - // node.js - module.exports = new Util(require('node-forge'), require('node-uuid'), require('crypto')); - } - -})(); \ No newline at end of file