forked from cloudacademy/static-website-example
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bon_encryption.js
118 lines (115 loc) · 4.57 KB
/
bon_encryption.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//
"use strict";
/**
* Private functions to handle local decryption of the token.
*/
// Object.defineProperty(exports, "__esModule", { value: true });
// exports.encryptDetached = exports.decryptSecureToken = exports.decryptDetached = exports.decrypt = exports.verifyVisitorInfo = void 0;
const crypto_1 = require("crypto");
const Pako = require("pako");
function getHmac(data, key, algorithm, outputEncoding) {
// @see https://nodejs.org/api/crypto.html#crypto_crypto_createhmac_algorithm_key
const hmac = crypto_1.createHmac(algorithm, key);
hmac.update(data);
return hmac.digest(outputEncoding);
}
/**
* @hidden
*/
function verifyVisitorInfo(info) {
if (typeof (info.action) !== "string" && info.action !== null) {
throw Error("Bad token");
}
if (typeof (info.expires) !== "number") {
throw Error("Bad token");
}
return info;
}
exports.verifyVisitorInfo = verifyVisitorInfo;
function decrypt(secureToken, secretKey) {
const components = secureToken.split(":");
if (components.length !== 4) {
throw Error("Invalid token");
}
const version = components[0];
const ivEncoded = components[1];
const encodedValue = components[2];
const hmac = components[3];
return decryptDetached(version, ivEncoded, encodedValue, hmac, secretKey);
}
exports.decrypt = decrypt;
function decryptDetached(version, ivEncoded, encodedValue, hmac, secretKey) {
const encryptionKey = secretKey.substring(0, 32);
const hashKey = secretKey.substring(secretKey.length - 32);
let encoding;
if (version === "1.0") {
encoding = "hex";
}
else if (version === "3") {
encoding = "base64";
}
else {
throw Error(`Unknown token version: '${version}'`);
}
// Make sure that someone with the correct hashKey performed the HMAC operation.
// This ensures that a 3rd-party has not tampered with the encodedValue.
if (hmac !== getHmac(encodedValue, hashKey, "sha256", encoding)) {
// console.log('HMAC: ', hmac);
// console.log('GET HMAC: ', getHmac(encodedValue, hashKey, "sha256", encoding));
// throw new Error("The HMAC does not match (wrong tokenEncryptionKey configured?)");
console.log("The HMAC does not match (wrong tokenEncryptionKey configured?)")
}
// Convert the iv back into a byte array.
const iv = Buffer.from(ivEncoded, encoding);
let decrypted;
const cipher = crypto_1.createDecipheriv("aes-256-cbc", encryptionKey, iv);
if (version === "1.0") {
decrypted = cipher.update(encodedValue, "hex", "utf8") + cipher.final("utf8");
}
else {
const compressedData = Buffer.concat([cipher.update(encodedValue, "base64"), cipher.final()]);
try {
decrypted = Pako.inflateRaw(compressedData, { to: "string" });
}
catch (e) {
throw new Error("Bad deflate data: " + e);
}
}
return decrypted;
}
exports.decryptDetached = decryptDetached;
module.exports = {
decryptSecureToken : function decryptSecureToken(secureToken, secretKey) {
const decrypted = decrypt(secureToken, secretKey);
let visitorInfo;
try {
visitorInfo = JSON.parse(decrypted);
}
catch (e) {
throw new Error("The decrypted token is not valid JSON!");
}
return verifyVisitorInfo(visitorInfo);
},
decrypt_abp_token_in_browser : function decrypt_abp_token_in_browser() {
var abp_token = document.getElementById("abp_token").value //decryptSecureToken(encrypted_token, priv_key)
var abp_decryption_key = document.getElementById("abp_decryption_key").value
// var abp_token_decryption_text = document.getElementById("abp_token") ;
console.log(abp_token)
console.log(abp_decryption_key)
document.getElementById("abp_token_decryption").innerHTML = JSON.stringify(abp.decryptSecureToken(abp_token, abp_decryption_key), null, 2);
}
};
// exports.decryptSecureToken = decryptSecureToken;
function encryptDetached(data, secretKey) {
const compressedData = Pako.deflateRaw(data);
const encryptionKey = secretKey.substring(0, 32);
const hashKey = secretKey.substring(secretKey.length - 32);
const iv = crypto_1.randomBytes(16);
const cipher = crypto_1.createCipheriv("aes-256-cbc", encryptionKey, iv);
let encodedValue = cipher.update(Buffer.from(compressedData), null, "base64");
encodedValue += cipher.final("base64");
const base64Iv = iv.toString("base64");
const hmac = getHmac(encodedValue, hashKey, "sha256", "base64");
return { iv: base64Iv, data: encodedValue, hmac };
}
exports.encryptDetached = encryptDetached;