diff --git a/.gitignore b/.gitignore index f17a962..e2b17e2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ .env package-lock.json yarn.lock +testBox.js \ No newline at end of file diff --git a/functions/createDigest.js b/functions/createDigest.js new file mode 100644 index 0000000..37d3433 --- /dev/null +++ b/functions/createDigest.js @@ -0,0 +1,9 @@ +const crypto = require("crypto"); +function createDigest(encodedData, secretKey, format) { + return crypto + .createHmac("sha1", secretKey) + .update(encodedData) + .digest(format); +} + +module.exports = createDigest; diff --git a/functions/decode.js b/functions/decode.js new file mode 100644 index 0000000..c73a898 --- /dev/null +++ b/functions/decode.js @@ -0,0 +1,18 @@ +const createDigest = require("./createDigest"); +const crypto = require("crypto"); + +function decode(value, secretKey) { + let [encodedData, sourceDigest] = value.split("!"); + if (!encodedData || !sourceDigest) throw new Error("invalid value(s)"); + const json = Buffer.from(encodedData, "base64").toString("utf8"); + const decodedData = JSON.parse(json); + const checkDigest = createDigest(encodedData, secretKey); + const digestsEqual = crypto.timingSafeEqual( + Buffer.from(sourceDigest, "base64"), + checkDigest + ); + if (!digestsEqual) throw new Error("invalid value(s)"); + return decodedData; +} + +module.exports = decode; diff --git a/functions/encode.js b/functions/encode.js new file mode 100644 index 0000000..6706d69 --- /dev/null +++ b/functions/encode.js @@ -0,0 +1,10 @@ +const createDigest = require("./createDigest"); +const crypto = require("crypto"); + +function encode(sourceData, secretKey) { + const json = JSON.stringify(sourceData); + const encodedData = Buffer.from(json).toString("base64"); + return `${encodedData}!${createDigest(encodedData, secretKey, "base64")}`; +} + +module.exports = encode; diff --git a/index.js b/index.js index 5dbf9f0..3e8330f 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,69 @@ const Cryptr = require("cryptr"); +const encode = require("./functions/encode"); +const decode = require("./functions/decode"); -function Randomizer(secret) { +var encypSep = ["#", "@", "$", "^", "&", "*", "?"]; + +function Randomizer(secretKey) { const ts = new Date().toUTCString(); - if (!secret || typeof secret !== "string") { - throw new Error("Cryptr: secret must be a non-0-length string"); - } - const cryptr = new Cryptr(secret); + if (!secretKey || typeof secretKey !== "string") { + throw new Error("Error: secret must be a non-0-length string"); + } + + const cryptr = new Cryptr(secretKey); const encryptedTs = cryptr.encrypt(ts); - console.log(encryptedTs); + this.showKey = function showKey() { - return secret; + return secretKey; }; + + this.getTs = function getTs() { + return ts; + }; + + this.encTs = function encTs() { + return encryptedTs; + }; + + this.sendHeader = function sendHeader() { + let setEncypSep = encypSep[Math.floor(Math.random() * encypSep.length)]; + var encryptHeader = + encryptedTs + setEncypSep + Buffer.from(encryptedTs).toString("base64"); + + const finalHeader = encode(encryptHeader, secretKey); + return finalHeader; + }; +} + +function Validator(secretKey, encryptedTs) { + const cryptr = new Cryptr(secretKey); + const ts = cryptr.decrypt(encryptedTs); + + this.verifyState = function verify(headers) { + const decodedHeaders = decode(headers, secretKey); + const encodedDecryptedTs = [ + decodedHeaders.slice(0, 250), + decodedHeaders.slice(251), + ]; + const decodeDecryptedTs = Buffer.from( + encodedDecryptedTs[1], + "base64" + ).toString("utf8"); + if (decodeDecryptedTs != encodedDecryptedTs[0]) { + return false; + } else if (cryptr.decrypt(encodedDecryptedTs[0]) != ts) { + return false; + } else return true; + }; + + this.showKey = function showKey() { + return secretKey; + }; + this.getTs = function getTs() { return ts; }; } -module.exports = Randomizer; +module.exports = { Randomizer, Validator }; diff --git a/package.json b/package.json index c96df68..ee73edd 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "hello": "echo hello world !!", - "test": "node ./test" + "test": "node ./test/sandbox" }, "repository": { "type": "git", @@ -27,8 +27,11 @@ }, "homepage": "https://github.com/bravo68web/randomizer#readme", "dependencies": { + "crypto": "^1.0.1", "crypto-js": "^4.0.0", "cryptr": "^6.0.2", + "extends-string": "^1.0.0", + "hash-wasm": "^4.8.0", "jose": "^3.14.0", "randomstring": "^1.2.1", "string-crypto": "^2.0.1", diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 136541d..0000000 --- a/test/index.js +++ /dev/null @@ -1,20 +0,0 @@ -const test = require("tape"); -const Randomizer = require("../"); - -const testSecret = "myTotalySecretKey"; -const testData = "bacon"; - -test("Initialization...", (t) => { - t.plan(1); - const Randomizr = new Randomizer(testSecret); - checkKey = Randomizr.showKey(); - t.equal(checkKey, testSecret, "Key Mention can be Used"); -}); - -test("Checking Timestamps...", (t) => { - t.plan(1); - const Randomizr = new Randomizer(testSecret); - var currentTs = new Date().toUTCString(); - var innerTs = Randomizr.getTs(); - t.equal(currentTs, innerTs, "TimeStamp Matched"); -}); diff --git a/test/sandbox.js b/test/sandbox.js new file mode 100644 index 0000000..8e4cfa5 --- /dev/null +++ b/test/sandbox.js @@ -0,0 +1,40 @@ +const test = require("tape"); +const { Randomizer, Validator } = require(".."); +const Cryptr = require("cryptr"); + +const testSecret = "myTotalySecretKey"; + +test("Initialization ...", async (t) => { + t.plan(1); + const Randomizr = new Randomizer(testSecret); + checkKey = Randomizr.showKey(); + t.equal(checkKey, testSecret, "Key Mention can be Used"); +}); + +test("Checking Timestamps ...", async (t) => { + t.plan(1); + const Randomizr = new Randomizer(testSecret); + var currentTs = new Date().toUTCString(); + var innerTs = Randomizr.getTs(); + t.equal(currentTs, innerTs, "TimeStamp Matched"); +}); + +test("Working ..........", async (t) => { + t.plan(1); + const Randomizr = new Randomizer(testSecret); + var currentTs = new Date().toUTCString(); + var innerTs = Randomizr.getTs(); + var hearders = await Randomizr.sendHeader(); + t.equal(true, typeof hearders == "string", "Headers Successfully Created"); +}); + +test("Verification.......", async (t) => { + t.plan(1); + const Randomizr = new Randomizer(testSecret); + var hearders = await Randomizr.sendHeader(); + const cryptr = new Cryptr(testSecret); + const encryptedTs = cryptr.encrypt(Randomizr.getTs()); + const Validatr = new Validator(testSecret, encryptedTs); + const verifyState = Validatr.verifyState(hearders); + t.equal(verifyState, true, "Verified"); +}); diff --git a/testBox.js b/testBox.js deleted file mode 100644 index cae9a5d..0000000 --- a/testBox.js +++ /dev/null @@ -1,10 +0,0 @@ -// console.log(new Date().toUTCString()); -const Cryptr = require("cryptr"); -const appEncryptKey = - "jWThgBwk4Awh7QQ82GDaz5QFcnVULu9Nk8bnU8sH6LcnfWfpeNaeYDLNGhSU47Yy"; -const cryptr = new Cryptr(appEncryptKey); -currentTs = new Date().toUTCString(); -const encryptedString = cryptr.encrypt(currentTs); -const decryptedString = cryptr.decrypt(encryptedString); - -console.log(encryptedString);