added jspl_encoder_wrapper.py

This commit is contained in:
2025-08-13 08:58:09 +02:00
parent 8a6444cb14
commit 9b191be6d6
3 changed files with 626 additions and 0 deletions
+439
View File
@@ -0,0 +1,439 @@
// JSPL的计算过程总结:
//
// 输入: 传入的会话ID或相关数据
// 哈希处理: 使用DJB2算法变种对输入进行哈希
// 种子生成: 结合时间戳和常量生成加密种子
// 数据收集: 收集各种浏览器指纹和环境信息
// 加密处理: 使用自定义的流加密算法对数据进行加密
// Base64编码: 最终使用自定义字符集进行Base64编码
// 这个函数生成的第三个返回值就是用于JSPL参数的加密字符串
var zn = (function () {
// 检查是否已经初始化
// if (Pn) {
// return Nn;
// }
Pn = true;
var n = "unknown"; // 默认返回值
var constantSeed = 11027890091; // 常量种子
var o = true; // 状态标志
// 字符串哈希函数 - DJB2算法的变种
function djb2HashString(str) {
if (!str) {
return n;
}
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = (hash << 8) - hash + str.charCodeAt(i) | 0;
}
return hash === 0 ? n : hash;
}
// 映射函数 - 用于Base64编码的自定义字符集
function mapChar(n) {
if (n > 37) {
return 59 + n;
} else if (n > 11) {
return 53 + n;
} else if (n > 1) {
return 46 + n;
} else {
return n * 50 + 45;
}
}
// 线性同余生成器 - 用于生成伪随机数
function lcg(n) {
return (n = (n ^= n << 13) ^ n >> 17) ^ n << 5;
}
// 加密随机数生成器
function createRandomGenerator(seed, initialValue) {
var state = seed;
var counter = -1;
var value = initialValue;
var firstCall = o;
o = false;
var buffer = null;
return function (peek) {
var result;
if (buffer !== null) {
result = buffer;
buffer = null;
} else {
if (++counter > 2) {
state = lcg(state);
counter = 0;
}
result = ((result = state >> 16 - counter * 8) ^ (firstCall ? --value : 0)) & 255;
if (peek) {
buffer = result;
}
}
return result;
};
}
// 主加密函数
return Nn = function (inputString, additionalData) {
// console.log("inputString:" + inputString)
// console.log("additionalData:" + additionalData)
// 混合输入数据生成种子
var seed = constantSeed ^ djb2HashString(inputString) ^ additionalData;
// 生成基于时间的随机数
var timeBasedRandom = lcg(lcg(Date.now() >> 3 ^ constantSeed) * constantSeed);
// 创建随机数生成器
var randomGenerator = createRandomGenerator(seed, timeBasedRandom);
// 存储加密数据的数组
var encryptedData = [];
var isFirstCall = true;
var callCounter = 0;
// UTF-8编码和加密函数
function utf8EncodeAndEncrypt(str) {
var bytes = [];
var byteIndex = 0;
// UTF-8编码
for (var i = 0; i < str.length; i++) {
var charCode = str.charCodeAt(i);
if (charCode < 128) {
bytes[byteIndex++] = charCode;
} else {
if (charCode < 2048) {
bytes[byteIndex++] = charCode >> 6 | 192;
} else {
if ((charCode & 64512) == 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) == 56320) {
charCode = 65536 + ((charCode & 1023) << 10) + (str.charCodeAt(++i) & 1023);
bytes[byteIndex++] = charCode >> 18 | 240;
bytes[byteIndex++] = charCode >> 12 & 63 | 128;
} else {
bytes[byteIndex++] = charCode >> 12 | 224;
}
bytes[byteIndex++] = charCode >> 6 & 63 | 128;
}
bytes[byteIndex++] = charCode & 63 | 128;
}
}
// XOR加密
for (var j = 0; j < bytes.length; j++) {
bytes[j] ^= randomGenerator();
}
return bytes;
}
// JSON序列化函数
function safeJsonStringify(obj) {
try {
return JSON.stringify(obj);
} catch (e) {
}
}
// 数据收集和加密函数
function collectAndEncrypt(key, value) {
// console.log("key:" + key)
// console.log("value:" + value)
if (!(typeof key != "string" || key.length == 0 || value && ["number", "string", "boolean"].indexOf(typeof value) == -1)) {
let serializedKey = safeJsonStringify(key);
// console.log("serializedKey:" + serializedKey)
value = safeJsonStringify(value);
// console.log("serializedValue:" + value)
if (key && value !== undefined && key !== "xt1") {
// 添加分隔符和加密数据
encryptedData.push(randomGenerator() ^ (encryptedData.length ? 44 : 123));
Array.prototype.push.apply(encryptedData, utf8EncodeAndEncrypt(serializedKey));
encryptedData.push(randomGenerator() ^ 58);
Array.prototype.push.apply(encryptedData, utf8EncodeAndEncrypt(value));
// 第一次调用时添加额外数据
if (isFirstCall) {
isFirstCall = false;
// var hsv = typeof window._hsv == "string" && window._hsv.length > 0 ||
// typeof window._hsv == "number" && !isNaN(window._hsv) ? window._hsv : 33;
//todo hsv 怎么拿到
var hsv = 33;
collectAndEncrypt("r3n", hsv);
}
}
}
}
var processedKeys = new Set();
// 返回三个函数的数组
return [
// 1. 主要的数据收集函数
collectAndEncrypt,
// 2. 带去重保护的数据收集函数
function (key, value) {
if (!processedKeys.has(key)) {
processedKeys.add(key);
collectAndEncrypt(key, value);
}
},
// 3. 最终生成加密字符串的函数
function (finalKey) {
var finalRandomGen = createRandomGenerator(djb2HashString(finalKey) ^ 1809053797, timeBasedRandom);
collectAndEncrypt("bpc", ++callCounter);
// 对收集的数据进行最终加密
var finalEncrypted = [];
for (var i = 0; i < encryptedData.length; i++) {
finalEncrypted.push(encryptedData[i] ^ finalRandomGen());
}
// 添加结束标记
finalEncrypted.push(randomGenerator(true) ^ 125 ^ finalRandomGen());
// Base64编码
var resultBytes = finalEncrypted;
var resultChars = [];
var baseValue = timeBasedRandom;
for (var pos = 0; pos < resultBytes.length;) {
var triplet = (--baseValue & 255 ^ resultBytes[pos++]) << 16 |
(--baseValue & 255 ^ resultBytes[pos++]) << 8 |
--baseValue & 255 ^ resultBytes[pos++];
resultChars.push(String.fromCharCode(mapChar(triplet >> 18 & 63)));
resultChars.push(String.fromCharCode(mapChar(triplet >> 12 & 63)));
resultChars.push(String.fromCharCode(mapChar(triplet >> 6 & 63)));
resultChars.push(String.fromCharCode(mapChar(triplet & 63)));
}
// 处理剩余字节
if (resultBytes.length % 3) {
resultChars.length -= 3 - (resultBytes.length % 3);
}
return resultChars.join("");
}
];
};
})();
// 创建一个工具函数来生成JSPL
function createJSPLGenerator(dateTimeStamp) {
return {
generate: function (sessionData, fingerprintData) {
// let dateTimeStamp = Math.floor(Date.now() / 1000)
// console.log("dateTimeStamp : " + dateTimeStamp)
// 使用会话数据作为输入
var functions = zn(sessionData, dateTimeStamp);
var collect = functions[1]; // 收集函数
var generate = functions[2]; //加密函数
// 收集指纹数据
for (var key in fingerprintData) {
if (fingerprintData.hasOwnProperty(key)) {
collect(key, fingerprintData[key]);
}
}
// 生成并返回JSPL
return generate("jspl");
}
};
}
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
var fingerprint = undefined
if (process.argv[2] != undefined) {
fingerprint = JSON.parse(process.argv[2])
}
// main
// let dateTimeStamp = Math.floor(Date.now() / 1000)
let dateTimeStamp = 1754908260
// console.log(dateTimeStamp)
// 使用示例
let jsplGenerator = createJSPLGenerator(dateTimeStamp);
// fingerprint = {
// "nddc": 1,
// "r3n": 33,
// "exp8": 0,
// "uid": null,
// "bci": true,
// "bcl": 0.8,
// "bct": "Infinity",
// "bdt": "Infinity",
// "dp0": false,
// "ucdv": false,
// "wdifrm": false,
// "iwgl": "undefined",
// "npmtm": false,
// "wdif": false,
// "wdifpnh": 2800984568,
// "lg": "fr-FR",
// "isb": false,
// "idp": true,
// "crt": 0,
// "vnd": "Google Inc.",
// "bid": "NA",
// "med": "defined",
// "pltod": false,
// "csssp": "",
// "awe": false,
// "phe": false,
// "dat": false,
// "nm": false,
// "geb": false,
// "sqt": false,
// "pf": "MacIntel",
// "hc": 8,
// "br_oh": 745,
// "br_ow": 393,
// "ua": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36",
// "wbd": false,
// "ts_mtp": 5,
// "mob": true,
// "lgs": ["fr-FR", "en-US", "zh-CN", "zh", "fr", "en"],
// "dvm": 4,
// "hcovdr": false,
// "plovdr": false,
// "ftsovdr": false,
// "orf": "debug",
// "ttst": 0.8517814137469564,
// "br_w": 393,
// "br_h": 745,
// "br_iw": 513,
// "br_ih": 847,
// "ars_w": 393,
// "ars_h": 876,
// "rs_w": 393,
// "rs_h": 876,
// "rs_cd": 24,
// "pr": 2.75,
// "so": "portrait-primary",
// "vco": "",
// "vcots": false,
// "vch": "probably",
// "vchts": true,
// "vcw": "probably",
// "vcwts": true,
// "vc3": "maybe",
// "vc3ts": false,
// "vcmp": "",
// "vcmpts": false,
// "vcq": "",
// "vcqts": false,
// "vc1": "probably",
// "vc1ts": true,
// "cssS": "3.93,0.39,12.24,9.75,5.64,10.98,13.46,2.19,6.51",
// "css0": "7,75,0",
// "css1": "9.74354,0.354646,-0.00922698,0.000685511,0.203723,-5.61673,-0.755238,0.0561098,-0.0279023,0.481607,-10.9534,0.813777,-0.375565,6.48243,-147.433,11.9534",
// "cssH": "15px",
// "plu": "",
// "plgod": false,
// "plg": 0,
// "plgne": "NA",
// "plgre": "NA",
// "plgof": "NA",
// "plggt": "NA",
// "mmt": "empty",
// "bchk": "3223aeb6721e0d0917e792818d193ac88dcd62fad5cad7bf7a2b2b473ecf58ee60f018dbdb1a5832e8dc6528387b0745971dbcd82387261e9a4e3f",
// "nt_tcp": 0,
// "nt_dns": 0,
// "nt_rd": 0,
// "nt_irt": -29.600000008940697,
// "nt_rt": 1129,
// "nt_tls": 6.700000002980232,
// "nt_ttf": 1166.7000000029802,
// "nt_swt": 22.900000005960464,
// "nt_csd": 411060,
// "nt_nhp": "h2",
// "nt_rdc": 0,
// "nt_it": "navigation",
// "nt_prs": 6.700000002980232,
// "nt_esc": 0,
// "nt_ttrd": null,
// "nt_le": 3.0999999940395355,
// "nt_dcle": 141.79999999701977,
// "nt_di": 1415.2000000029802,
// "nt_dc": 2862.6000000089407,
// "ccsT": "Error\nat S (https://d.digital.hermes/tags.js:173:22)\nat Un.C (https://d.digital.hermes/tags.js:1252:41\nat nrWrapper (https://www.hermes.com/fr/fr/category/femme/Sacs%20et%20pochettes%20pour%20Femme%20_%20Herme%CC%80s%20France.html:7:13468)",
// "ccsB": "tags.js:1252:41 at nrWrapper (sac-p-tit-arcon-H085871CKAO.html:7:13468)",
// "ccsH": "1050544242",
// "ccsV": ",993b46baf0942a343b7e6b02fa3f8eef64727f077d3b0055af56e6994dcaf046",
// "muev": false,
// "pro_t": true,
// "wglo": true,
// "prso": true,
// "wbst": true,
// "psn": true,
// "edp": true,
// "addt": true,
// "wsdc": true,
// "ccsr": true,
// "nuad": true,
// "bcda": true,
// "idn": true,
// "capi": true,
// "svde": true,
// "vpbq": true,
// "mq": "aptr:coarse,ahvr:none",
// "aco": "probably",
// "acots": false,
// "acmp": "probably",
// "acmpts": true,
// "acw": "probably",
// "acwts": false,
// "acma": "maybe",
// "acmats": false,
// "acaa": "probably",
// "acaats": true,
// "ac3": "",
// "ac3ts": false,
// "acf": "probably",
// "acfts": false,
// "acmp4": "maybe",
// "acmp4ts": false,
// "acmp3": "probably",
// "acmp3ts": false,
// "acwm": "maybe",
// "acwmts": false,
// "ocpt": false,
// "ckwa": false,
// "spwn": false,
// "emt": false,
// "bfr": false,
// "tz": -120,
// "hdn": false,
// "xt1": false,
// "cdhf": false,
// "eva": 33,
// "cokys": ",loadTimes,csi,app",
// "ecpc": false,
// "nhi": ",64,true,Nexus 5,Android,6.0,138.0.7204.184,false",
// "k_lyts": 48,
// "k_lytk": "kg20va`l\u00a7'w8mh.71pdfoqcn[zy365x/\\,-4bt9siu=j;r]e",
// "emd": "k:ai,vi,ao",
// "wwl": false,
// "glvd": "Google Inc. (ARM)",
// "glrd": "ANGLE (ARM,Mali-G57 MC2,OpenGL ES 3.2)",
// "tzp": "Europe/Paris",
// "isf": true,
// "isf2": false,
// "dt": false,
// "fph": 416468867,
// "jset": 1754750959
// }
// console.log("received fringerprint is :"+fingerprint)
// console.log(fingerprint)
let jspl = jsplGenerator.generate("user_session_12345", fingerprint);
console.log(jspl);