From 2f4fcffbafb7ad005ae3cff625a36634f225f7c9 Mon Sep 17 00:00:00 2001 From: jusax23 Date: Fri, 22 Oct 2021 18:15:37 +0200 Subject: [PATCH] Added "no Module" --- crypto.js | 4 - crypto.nomodule.js | 325 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 325 insertions(+), 4 deletions(-) create mode 100644 crypto.nomodule.js diff --git a/crypto.js b/crypto.js index ea21379..1c1337f 100644 --- a/crypto.js +++ b/crypto.js @@ -320,8 +320,4 @@ const C = { } }; -if(typeof module != "undefined"){ - module.exports = C; -} - export default C; diff --git a/crypto.nomodule.js b/crypto.nomodule.js new file mode 100644 index 0000000..7915faf --- /dev/null +++ b/crypto.nomodule.js @@ -0,0 +1,325 @@ +var node = false; + +if (typeof require != "undefined") { + crypto = require('crypto'); + if(typeof crypto.webcrypto != "undefined"){ + crypto = crypto.webcrypto; + console.log("subtle"); + }else{ + node = true; + console.log("node crypto"); + } +}/*else{ + crypto = window.crypto; +}*/ + +var asciiList = []; +for (var i = 0; i < 256; i++) { + asciiList[i]=String.fromCharCode(i); +} + +const C = { + sha256: async (msgBuffer) => { + return node ? new Uint8Array(crypto.createHash("sha256").update(msgBuffer).digest()) : + new Uint8Array(await crypto.subtle.digest('SHA-256', msgBuffer)); + }, + random: async (length) => { + return node ? crypto.randomFillSync(new Uint8Array(length)) : + crypto.getRandomValues(new Uint8Array(length)); + }, + randomKey: async (length) => { + return C.decode(await C.random(length)); + }, + encode : (data)=>{ + if(node){ + return new Uint8Array(Buffer.from(data,"binary")); + }else{ + var out = new Uint8Array(data.length); + for (var i = 0; i < data.length; i++) { + out[i] = data.charCodeAt(i); + } + return out;//new Uint8Array(data.split("").map(d => d.charCodeAt(0))); + } + }, + decode : (data)=>{ + if(node){ + return Buffer.from(data).toString("binary"); + }else{ + var out = []; + var i = 0; + var limit = i - (i%16); + while (i < limit) { + out.push(asciiList[data[i]]+asciiList[data[i+1]]+asciiList[data[i+2]]+asciiList[data[i+3]]+asciiList[data[i+4]]+asciiList[data[i+5]]+asciiList[data[i+6]]+asciiList[data[i+7]]+asciiList[data[i+8]]+asciiList[data[i+9]]+asciiList[data[i+10]]+asciiList[data[i+11]]+asciiList[data[i+12]]+asciiList[data[i+13]]+asciiList[data[i+14]]+asciiList[data[i+15]]); + i+=16; + } + while (i < data.length) { + out.push(asciiList[data[i]]); + i++; + } + return out.join(""); + } + }, + atob: (data)=>node?Buffer.from(data,"base64").toString("binary"):atob(data), //base to ascii + btoa: (data)=>node?Buffer.from(data,"binary").toString("base64"):btoa(data), //ascii to base + pad: (data) => { + var length = 16 - (data.length % 16); + var mergedArray = new Uint8Array(data.length+length); + mergedArray.set(data); + mergedArray.set(new Uint8Array(length).fill(length), data.length); + return mergedArray; + }, + unpad: (data) => { + return data.slice(0, -data[data.length - 1]); + }, + AES:{ + bytes_to_key: async (bytes, salt, output = 48) => { + var data = new Uint8Array([...bytes, ...salt]); + var key = new Uint8Array(); + var final_key = new Uint8Array(); + while (final_key.length < output) { + key = await C.sha256(new Uint8Array([...key, ...data])); + final_key = new Uint8Array([...final_key, ...key]); + } + return final_key.slice(0, output); + }, + encryptData: async (rawdata, rawkey) => { + var salt = await C.random(8); + var key_iv = await C.AES.bytes_to_key(rawkey, salt, 32 + 16); + var key = key_iv.slice(0, 32); + var iv = key_iv.slice(32); + var aes; + if(node){ + let cipher = crypto.createCipheriv('aes-256-cbc', key, iv); + let encrypted = cipher.update(C.pad(rawdata)); + aes = new Uint8Array(Buffer.concat([encrypted, cipher.final()])); + }else{ + aes = new Uint8Array(await crypto.subtle.encrypt({name: "AES-CBC",iv},await crypto.subtle.importKey("raw",key,"AES-CBC",true,["encrypt", "decrypt"]),C.pad(rawdata))); + } + var mergedArray = new Uint8Array(aes.length+16); + mergedArray.set([83, 97, 108, 116, 95, 50, 53, 54]); + mergedArray.set(salt,8); + mergedArray.set(aes,16); + return mergedArray; + }, + encrypt: async (message, passphrase) => { + var rawdata = C.encode(message); + var rawkey = C.encode(passphrase); + var step = await C.AES.encryptData(rawdata,rawkey); + return C.decode(step); + }, + decryptData: async (rawdata, rawkey) => { + var check = [83, 97, 108, 116, 95, 50, 53, 54]; + for (var i = 0; i < check.length; i++) { + if(check[i]!=rawdata[i])return null; + } + var salt = rawdata.slice(8,16); + var key_iv = await C.AES.bytes_to_key(rawkey, salt, 32 + 16); + var key = key_iv.slice(0, 32); + var iv = key_iv.slice(32); + if(node){ + let cipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv); + let encrypted = cipher.update(rawdata.slice(16)); + return C.unpad(new Uint8Array(Buffer.concat([encrypted, cipher.final()]))); + }else{ + return C.unpad( + new Uint8Array (await crypto.subtle.decrypt( + {name: "AES-CBC",iv}, + await crypto.subtle.importKey("raw",key,"AES-CBC",true,["encrypt", "decrypt"]), + rawdata.slice(16) + )) + ); + } + }, + decrypt: async (message, passphrase) => { + var rawdata = C.encode(message); + var rawkey = C.encode(passphrase); + try { + var step = await C.AES.decryptData(rawdata,rawkey); + return C.decode(step); + } catch (e) { + return null; + } + }, + }, + RSA:{ + generateEncryptionKey: async () =>{ + if(node){ + var { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {modulusLength: 4096,publicExponent:0x010001,hashAlgorithm:"sha256"}); + return {publicKey: C.decode(new Uint8Array( publicKey.export({type:"spki", format:"der"}))), + privateKey:C.decode(new Uint8Array(privateKey.export({type:"pkcs8",format:"der"})))}; + }else{ + var keyPair = await crypto.subtle.generateKey( + {name: "RSA-OAEP",modulusLength: 4096,publicExponent: new Uint8Array([1, 0, 1]),hash: "SHA-256"}, + true, + ["encrypt", "decrypt"] + ); + return {privateKey:C.decode(new Uint8Array(await crypto.subtle.exportKey("pkcs8",keyPair.privateKey))), + publicKey: C.decode(new Uint8Array(await crypto.subtle.exportKey("spki", keyPair.publicKey )))}; + } + }, + generateSigningKey: async () =>{ + if(node){ + var { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {modulusLength: 4096,publicExponent:0x010001,hashAlgorithm:"sha256"}); + return {publicKey: C.decode(new Uint8Array( publicKey.export({type:"spki", format:"der"}))), + privateKey:C.decode(new Uint8Array(privateKey.export({type:"pkcs8",format:"der"})))}; + }else{ + var keyPair = await crypto.subtle.generateKey( + {name: "RSA-PSS",modulusLength: 4096,publicExponent: new Uint8Array([1, 0, 1]),hash: "SHA-256"}, + true, + ["sign", "verify"] + ); + return {privateKey:C.decode(new Uint8Array(await crypto.subtle.exportKey("pkcs8",keyPair.privateKey))), + publicKey: C.decode(new Uint8Array(await crypto.subtle.exportKey("spki", keyPair.publicKey )))}; + } + }, + encrypt: async (message, publicKey) => { + var rawdata = C.encode(message); + var step; + if(node){ + var rawkey = crypto.createPublicKey({key:C.encode(publicKey),format:"der",type:"spki"}); + //console.log("d",rawkey); + step = crypto.publicEncrypt({ + key: rawkey, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + oaepHash: "sha256", + }, Buffer.from(rawdata)); + }else{ + var rawkey = await crypto.subtle.importKey("spki",C.encode(publicKey),{name: "RSA-OAEP",hash: "SHA-256"},true,["encrypt"]); + step = await crypto.subtle.encrypt({name: "RSA-OAEP"},rawkey,rawdata); + } + return C.decode(new Uint8Array(step)); + }, + decrypt: async (message, privateKey) => { + var rawdata = C.encode(message); + if(node){ + var rawkey = crypto.createPrivateKey({key:C.encode(privateKey),format:"der",type:"pkcs8"}); + try { + var step = crypto.privateDecrypt({ + key: rawkey, + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + oaepHash: "sha256", + }, Buffer.from(rawdata)); + return C.decode(new Uint8Array(step)); + } catch (e) { + return null; + } + }else{ + var rawkey = await crypto.subtle.importKey("pkcs8",C.encode(privateKey),{name: "RSA-OAEP",hash: "SHA-256"},true,["decrypt"]); + try { + var step = await crypto.subtle.decrypt({name: "RSA-OAEP"},rawkey,rawdata); + return C.decode(new Uint8Array(step)); + } catch (e) { + console.log(e); + return null; + } + } + + }, + sign:async (message, privateKey) => { + var rawdata = C.encode(message); + var step; + if(node){ + var rawkey = crypto.createPrivateKey({key:C.encode(privateKey),format:"der",type:"pkcs8"}); + step = crypto.sign("sha256", Buffer.from(rawdata), { + key: rawkey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength:32 + }); + }else{ + var rawkey = await crypto.subtle.importKey("pkcs8",C.encode(privateKey),{name: "RSA-PSS",hash: "SHA-256"},true,["sign"]); + step = await crypto.subtle.sign( + { + name: "RSA-PSS", + saltLength: 32, + }, + rawkey, + rawdata + ); + } + return C.decode(new Uint8Array(step)); + }, + verify:async (message, signature, publicKey) => { + var rawdata = C.encode(message); + var rawsig = C.encode(signature); + var step; + if(node){ + var rawkey = crypto.createPublicKey({key:C.encode(publicKey),format:"der",type:"spki"}); + step = crypto.verify( + "sha256", + Buffer.from(rawdata), + { + key: rawkey, + padding: crypto.constants.RSA_PKCS1_PSS_PADDING, + saltLength:32 + }, + Buffer.from(rawsig) + ); + }else{ + var rawkey = await crypto.subtle.importKey("spki",C.encode(publicKey),{name: "RSA-PSS",hash: "SHA-256"},true,["verify"]); + step = await crypto.subtle.verify( + { + name: "RSA-PSS", + saltLength: 32, + }, + rawkey, + rawsig, + rawdata + ); + } + + return step;// ? "valid" : "invalid"; + } + }, + communicate:{ + encrypt: async (message,publicKey)=>{ + var randKey = await C.randomKey(32); + var send = { + d: await C.AES.encrypt(message,randKey), + k: await C.RSA.encrypt(randKey,publicKey) + }; + return JSON.stringify(send); + }, + decrypt: async (data,privateKey)=>{ + try { + let {d,k} = JSON.parse(data); + if(typeof d != "string" || typeof k != "string")throw "invalid Data"; + var randKey = await C.RSA.decrypt(k,privateKey); + if(randKey == null) throw "invalid async Key"; + var out = await C.AES.decrypt(d,randKey); + if(out == null) throw "invalid sync Key"; + return out; + } catch (e) { + return null; + } + }, + //Message to send, reomte publicKey, own privateKey, my id so that the other one knows how i am (can be empty) + encryptSign: async (message,publicKey,privateKey,id)=>{ + return await C.communicate.encrypt(JSON.stringify({ + d:message, + i:id, + s:await C.RSA.sign(message,privateKey) + }),publicKey); + }, + //Data to decrypt, my privateKey, callback to get reomtes publicKey with id + decryptSign: async (data,privateKey,publicKeyCall)=>{ + try { + var inn = await C.communicate.decrypt(data,privateKey); + if(inn == null)throw "invalid privateKey"; + inn = JSON.parse(inn); + if(typeof inn.d == "undefined"||typeof inn.i != "string"||typeof inn.s != "string") throw "invalid Data"; + let {d,i,s} = inn; + var publicKey = publicKeyCall(i); + var okay = await C.RSA.verify(d,s,publicKey); + if(!okay) throw "wrong Public Key"; + return d; + } catch (e) { + console.log(e); + return null; + } + }, + } +}; + +if(typeof module != "undefined"){ + module.exports = C; +}