Arkose_MatchKey算法层分析

前言

Arkose-MatchKey验证码国外有很多的网站在用到,那么话不多说来分析下

抓包分析流程

1.请求token生成

2.携带token请求图片

3.发包校验

跟栈分析

跟到这里大概率是AES加密

如果有需要的话可以解下混淆也比较简单每个函数的作用都嵌套了一个解密函数

分析key和iv生成

key生成的位置

m参数生成位置
以下是m生成的算法

1
2
3
4
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
f = (new Date)["getTime"]() / 1e3,
l = navigator["userAgent"],
p = Math["round"](f - f % 21600),

剩下的Vr函数其实就是随机的字节数组生成算法

1
2
3
4
function Vr(arrayType, length) {
const array = new arrayType(length);
return crypto.randomFillSync(array);
}

gn函数就是字节数组转16进制字符串

1
2
3
4
5
function bytesToHexString(bytes) {
return Array.from(bytes)
.map(byte => byte.toString(16).padStart(2, '0'))
.join('');
}

最后一个dn函数的算法是什么呢?
最后的dn函数跟栈看下
跟栈
发现这个是多轮的哈希在结合前面分析的可以得出
大概率是sha256加密的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function dn(t, e) {
// t 是一个字符串,e 是一个十六进制字符串
// 将 e 转换为普通字符串并与 t 拼接
const u = t + hexToString(e);

// 创建 s 数组存储哈希值
const s = [];

// 第一轮哈希
s[0] = sr().update(u, true);

// 初始化结果
let f = s[0];

// 多轮哈希
for (let l = 1; l < 3; l++) {
s[l] = sr().update(s[l - 1] + u, true);
f += s[l];
}

// 转换为字节数组并截取前32字节
return stringToUint8Array(f.substring(0, 32));
}

加密的明文参数是

1
data='[{"key":"api_type","value":"js"},{"key":"f","value":"553862b7c499eee92a879bbf27e1c6f1"},{"key":"n","value":"MTc1MDMxMTE5Mw=="},{"key":"wh","value":"758da5ac68f0447b3361d5bb864bf2f8|cc7fecdd5c8bec57541ae802c7648eed"},{"key":"enhanced_fp","value":[{"key":"webgl_extensions","value":"ANGLE_instanced_arrays;EXT_blend_minmax;EXT_clip_control;EXT_color_buffer_half_float;EXT_depth_clamp;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_polygon_offset_clamp;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;EXT_texture_mirror_clamp_to_edge;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_blend_func_extended;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_multi_draw;WEBGL_polygon_mode"},{"key":"webgl_extensions_hash","value":"7300c23f4e6fa34e534fc99c1b628588"},{"key":"webgl_renderer","value":"WebKit WebGL"},{"key":"webgl_vendor","value":"WebKit"},{"key":"webgl_version","value":"WebGL 1.0 (OpenGL ES 2.0 Chromium)"},{"key":"webgl_shading_language_version","value":"WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)"},{"key":"webgl_aliased_line_width_range","value":"[1, 1]"},{"key":"webgl_aliased_point_size_range","value":"[1, 1024]"},{"key":"webgl_antialiasing","value":"yes"},{"key":"webgl_bits","value":"8,8,24,8,8,0"},{"key":"webgl_max_params","value":"16,32,16384,1024,16384,16,16384,30,16,16,4095"},{"key":"webgl_max_viewport_dims","value":"[32767, 32767]"},{"key":"webgl_unmasked_vendor","value":"Google Inc. (NVIDIA)"},{"key":"webgl_unmasked_renderer","value":"ANGLE (NVIDIA, NVIDIA GeForce RTX 2060 (0x00001F08) Direct3D11 vs_5_0 ps_5_0, D3D11)"},{"key":"webgl_vsf_params","value":"23,127,127,23,127,127,23,127,127"},{"key":"webgl_vsi_params","value":"0,31,30,0,31,30,0,31,30"},{"key":"webgl_fsf_params","value":"23,127,127,23,127,127,23,127,127"},{"key":"webgl_fsi_params","value":"0,31,30,0,31,30,0,31,30"},{"key":"webgl_hash_webgl","value":"89f3265915d19d097c9f67ed49c1f46d"},{"key":"user_agent_data_brands","value":"Google Chrome,Chromium,Not/A)Brand"},{"key":"user_agent_data_mobile","value":false},{"key":"navigator_connection_downlink","value":0.75},{"key":"navigator_connection_downlink_max","value":null},{"key":"network_info_rtt","value":500},{"key":"network_info_save_data","value":false},{"key":"network_info_rtt_type","value":null},{"key":"screen_pixel_depth","value":24},{"key":"navigator_device_memory","value":8},{"key":"navigator_pdf_viewer_enabled","value":true},{"key":"navigator_languages","value":"zh-CN,zh"},{"key":"window_inner_width","value":0},{"key":"window_inner_height","value":0},{"key":"window_outer_width","value":1920},{"key":"window_outer_height","value":1032},{"key":"browser_detection_firefox","value":false},{"key":"browser_detection_brave","value":false},{"key":"browser_api_checks","value":["permission_status: true","eye_dropper: true","audio_data: true","writable_stream: true","css_style_rule: true","navigator_ua: true","barcode_detector: false","display_names: true","contacts_manager: false","svg_discard_element: false","usb: defined","media_device: defined","playback_quality: true"]},{"key":"browser_object_checks","value":"554838a8451ac36cb977e719e9d6623c"},{"key":"29s83ih9","value":"68934a3e9455fa72420237eb05902327â\x81£"},{"key":"audio_codecs","value":"{\\"ogg\\":\\"probably\\",\\"mp3\\":\\"probably\\",\\"wav\\":\\"probably\\",\\"m4a\\":\\"maybe\\",\\"aac\\":\\"probably\\"}"},{"key":"audio_codecs_extended_hash","value":"805036349642e2569ec299baed02315b"},{"key":"video_codecs","value":"{\\"ogg\\":\\"\\",\\"h264\\":\\"probably\\",\\"webm\\":\\"probably\\",\\"mpeg4v\\":\\"\\",\\"mpeg4a\\":\\"\\",\\"theora\\":\\"\\"}"},{"key":"video_codecs_extended_hash","value":"67b509547efe3423d32a3a70a2553c16"},{"key":"media_query_dark_mode","value":false},{"key":"f9bf2db","value":"{\\"pc\\":\\"no-preference\\",\\"ah\\":\\"hover\\",\\"ap\\":\\"fine\\",\\"p\\":\\"fine\\",\\"h\\":\\"hover\\",\\"u\\":\\"fast\\",\\"prm\\":\\"reduce\\",\\"prt\\":\\"no-preference\\",\\"s\\":\\"enabled\\",\\"fc\\":\\"none\\"}"},{"key":"headless_browser_phantom","value":false},{"key":"headless_browser_selenium","value":false},{"key":"headless_browser_nightmare_js","value":false},{"key":"headless_browser_generic","value":4},{"key":"1l2l5234ar2","value":"1750311066787â\x81£"},{"key":"document__referrer","value":""},{"key":"window__ancestor_origins","value":["https://www.arkoselabs.com"]},{"key":"window__tree_index","value":[0]},{"key":"window__tree_structure","value":"[[]]"},{"key":"window__location_href","value":"https://client-api.arkoselabs.com/v2/2.14.0/enforcement.673c2bc2a64779bc3ca40cdf91f2a7ec.html"},{"key":"client_config__sitedata_location_href","value":"https://www.arkoselabs.com/arkose-matchkey/"},{"key":"client_config__language","value":null},{"key":"client_config__surl","value":"https://client-api.arkoselabs.com"},{"key":"c8480e29a","value":"165ee51d4a3e27bfeee660c40851de9fâ\x81¢"},{"key":"client_config__triggered_inline","value":false},{"key":"mobile_sdk__is_sdk","value":false},{"key":"audio_fingerprint","value":"124.04347527516074"},{"key":"navigator_battery_charging","value":true},{"key":"media_device_kinds","value":null},{"key":"media_devices_hash","value":null},{"key":"navigator_permissions_hash","value":"67419471976a14a1430378465782c62d"},{"key":"math_fingerprint","value":"0ce80c69b75667d69baedc0a70c82da7"},{"key":"supported_math_functions","value":"67d1759d7e92844d98045708c0a91c2f"},{"key":"screen_orientation","value":"landscape-primary"},{"key":"rtc_peer_connection","value":5},{"key":"4b4b269e68","value":"39a6fa63-c69f-458f-a9a6-2f9f27757dd6"},{"key":"6a62b2a558","value":"673c2bc2a64779bc3ca40cdf91f2a7ec"},{"key":"is_keyless","value":false},{"key":"c2d2015","value":"29d13b1af8803cb86c2697345d7ea9eb"},{"key":"43f2d94","value":false},{"key":"20c15922","value":true},{"key":"4f59ca8","value":null},{"key":"3ea7194","value":{"supported":true,"formats":["HDR10","HLG"],"isHDR":false}},{"key":"05d3d24","value":"ab77dc7ca26f868960ff6340cce29973"},{"key":"speech_default_voice","value":"Google Deutsch || de-DE"},{"key":"speech_voices_hash","value":"a0c90ca98043f0489c1e731e233b937e"},{"key":"83eb055","value":false},{"key":"4ca87df3d1","value":"MTI1MTczLDAsMTI4Niw1MjQ7MTI1MTk3LDAsMTM5Miw1MDA7MTI1MjE0LDAsMTUyMSw0OTA7MTI1MzgwLDAsMTQ1Niw1NjY7MTI1Mzk3LDAsMTI3MCw2MTQ7MTI1NDE0LDAsMTE3NSw2NDM7MTI1NDMwLDAsMTEwNyw2NTU7MTI1NDM5LDAsMTA4OSw2NjE7MTI1OTE4LDAsNzQwLDEyNjsxMjU5MjUsMCw3NTAsMTA2OzEyNTkzMiwwLDc2Myw4MjsxMjU5NDEsMCw3NzEsNzI7MTI1OTUwLDAsNzc4LDYxOzEyNTk1NiwwLDc4Myw1NTsxMjYwMTQsMCw3ODgsNjU7MTI2MDIyLDAsNzg5LDcxOzEyNjAzNywwLDc4OSw4MTsxMjYwNTMsMCw3ODksODk7MTI2MDYwLDAsNzkzLDk5OzEyNjA2OSwwLDc5NSwxMDg7MTI2MDc2LDAsNzk5LDExNzsxMjYwODUsMCw4MDMsMTI2OzEyNjA5MywwLDgwOSwxMzY7MTI2MTA3LDAsODE3LDE0NjsxMjcyMjIsMCw4NTQsNTQ3OzEyNzIyOCwwLDg0Nyw1Mzk7MTI3MjM2LDAsODQxLDUzMjsxMjcyNDUsMCw4MzQsNTIyOzEyNzI1MywwLDgyNiw1MTM7MTI3MjY5LDAsODE1LDUwMDsxMjcyNzcsMCw4MTAsNDkwOzEyNzI4NSwwLDgwNiw0ODQ7MTI3MjkzLDAsODAxLDQ3NDsxMjczMDEsMCw3OTksNDY2OzEyNzMwOCwwLDc5Nyw0NjE7MTI3MzE3LDAsNzk1LDQ1NjsxMjczMzQsMCw3OTUsNDUwOzEyNzM3MiwwLDc5NSw0NDM7MTI3NDQ0LDAsNzk4LDQzNzsxMjc1MTcsMCw4MDIsNDMzOzEyNzU0MiwxLDgwMiw0MzM7MTI3NjIxLDIsODAyLDQzMzs="},{"key":"867e25e5d4","value":"Ow=="},{"key":"d4a306884c","value":"MTI1MDY0LDAsMTQ7MTI1MTQwLDEsMTQ7"}]},{"key":"fe","value":["DNT:unknown","L:zh-CN","D:24","PR:1","S:1920,1080","AS:1920,1032","TO:-480","SS:true","LS:true","IDB:true","B:false","ODB:false","CPUC:unknown","PK:Win32","CFP:-642173219","FR:false","FOS:false","FB:false","JSF:Arial,Arial Black,Arial Narrow,Book Antiqua,Bookman Old Style,Calibri,Cambria,Cambria Math,Century,Century Gothic,Century Schoolbook,Comic Sans MS,Consolas,Courier,Courier New,Garamond,Georgia,Helvetica,Impact,Lucida Bright,Lucida Calligraphy,Lucida Console,Lucida Fax,Lucida Handwriting,Lucida Sans,Lucida Sans Typewriter,Lucida Sans Unicode,Microsoft Sans Serif,Monotype Corsiva,MS Gothic,MS PGothic,MS Reference Sans Serif,MS Sans Serif,MS Serif,Palatino Linotype,Segoe Print,Segoe Script,Segoe UI,Segoe UI Light,Segoe UI Semibold,Segoe UI Symbol,Tahoma,Times,Times New Roman,Trebuchet MS,Verdana,Wingdings,Wingdings 2,Wingdings 3","P:Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,PDF Viewer,WebKit built-in PDF","T:0,false,false","H:12","SWF:false"]},{"key":"ife_hash","value":"8979c33a31ba3c31d9f47c0571e35fa9"},{"key":"jsbd","value":"{\\"HL\\":2,\\"NCE\\":true,\\"DT\\":\\"\\",\\"NWD\\":\\"false\\",\\"DMTO\\":1,\\"DOTO\\":1}"}]'
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
function aesEncrypt(plaintext, key, iv) {
try {
// 确保密钥长度为32字节(256位)
if (Buffer.isBuffer(key)) {
if (key.length !== 32) {
throw new Error('密钥必须是32字节(256位)');
}
} else if (typeof key === 'string') {
if (Buffer.from(key).length !== 32) {
throw new Error('密钥必须是32字节(256位)');
}
}

// 确保IV长度为16字节(128位)
if (Buffer.isBuffer(iv)) {
if (iv.length !== 16) {
throw new Error('IV必须是16字节(128位)');
}
} else if (typeof iv === 'string') {
if (Buffer.from(iv).length !== 16) {
throw new Error('IV必须是16字节(128位)');
}
}

// 创建加密器
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);

// 加密数据
let encrypted = cipher.update(plaintext, 'utf8', 'base64');
encrypted += cipher.final('base64');

return {
encrypted: encrypted,
iv: iv.toString('hex'),
key: key.toString('hex'),
algorithm: 'aes-256-cbc'
};
} catch (error) {
throw new Error(`加密失败: ${error.message}`);
}
}

生成算法

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

const crypto = require('crypto');


const Wr = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'-'9' -> 0-9
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'-'F' -> 10-15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 'a'-'f' -> 10-15
];

function hexToString(hexStr) {
let result = "";
let length = hexStr.length;
let i = 0;

while (length > 1) {
const char1 = hexStr.charAt(i++);
const char2 = hexStr.charAt(i++);
const byte1 = Wr[char1.charCodeAt(0)]; // 十六进制字符的高4位
const byte2 = Wr[char2.charCodeAt(0)]; // 十六进制字符的低4位

result += String.fromCharCode((byte1 << 4) + byte2);
length -= 2;
}

return result;
}
function sr() {
return {
// 模拟原函数中的加密处理
update: function(data, raw) {
const hash = crypto.createHash('sha256');
hash.update(data);
return raw ? hash.digest('binary') : hash.digest('hex');
}
};
}

function stringToUint8Array(str) {
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}

function dn(t, e) {
// t 是一个字符串,e 是一个十六进制字符串
// 将 e 转换为普通字符串并与 t 拼接
const u = t + hexToString(e);

// 创建 s 数组存储哈希值
const s = [];

// 第一轮哈希
s[0] = sr().update(u, true);

// 初始化结果
let f = s[0];

// 多轮哈希
for (let l = 1; l < 3; l++) {
s[l] = sr().update(s[l - 1] + u, true);
f += s[l];
}

// 转换为字节数组并截取前32字节
return stringToUint8Array(f.substring(0, 32));
}

function Vr(arrayType, length) {
const array = new arrayType(length);
return crypto.randomFillSync(array);
}

function bytesToHexString(bytes) {
return Array.from(bytes)
.map(byte => byte.toString(16).padStart(2, '0'))
.join('');
}

f = (new Date)["getTime"]() / 1e3
p = Math["round"](f - f % 21600)

m = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" + p

const b = Vr(Uint8Array, 8)
const b2 = Vr(Uint8Array, 16)
const hexB = bytesToHexString(b);
console.log(`随机字节数组: [${Array.from(b).join(', ')}]`);
console.log(`十六进制表示: ${hexB}`);



/**
* AES-256-CBC 加密函数
* @param {string|Buffer} plaintext - 要加密的明文
* @param {string|Buffer} key - 32字节(256位)的密钥
* @param {string|Buffer} iv - 16字节(128位)的初始化向量
* @returns {Object} - 包含加密结果的对象
*/
function aesEncrypt(plaintext, key, iv) {
try {
// 确保密钥长度为32字节(256位)
if (Buffer.isBuffer(key)) {
if (key.length !== 32) {
throw new Error('密钥必须是32字节(256位)');
}
} else if (typeof key === 'string') {
if (Buffer.from(key).length !== 32) {
throw new Error('密钥必须是32字节(256位)');
}
}

// 确保IV长度为16字节(128位)
if (Buffer.isBuffer(iv)) {
if (iv.length !== 16) {
throw new Error('IV必须是16字节(128位)');
}
} else if (typeof iv === 'string') {
if (Buffer.from(iv).length !== 16) {
throw new Error('IV必须是16字节(128位)');
}
}

// 创建加密器
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);

// 加密数据
let encrypted = cipher.update(plaintext, 'utf8', 'base64');
encrypted += cipher.final('base64');

return {
encrypted: encrypted,
iv: iv.toString('hex'),
key: key.toString('hex'),
algorithm: 'aes-256-cbc'
};
} catch (error) {
throw new Error(`加密失败: ${error.message}`);
}
}
data='[{"key":"api_type","value":"js"},{"key":"f","value":"553862b7c499eee92a879bbf27e1c6f1"},{"key":"n","value":"MTc1MDMxMTE5Mw=="},{"key":"wh","value":"758da5ac68f0447b3361d5bb864bf2f8|cc7fecdd5c8bec57541ae802c7648eed"},{"key":"enhanced_fp","value":[{"key":"webgl_extensions","value":"ANGLE_instanced_arrays;EXT_blend_minmax;EXT_clip_control;EXT_color_buffer_half_float;EXT_depth_clamp;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_polygon_offset_clamp;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;EXT_texture_mirror_clamp_to_edge;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_blend_func_extended;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_multi_draw;WEBGL_polygon_mode"},{"key":"webgl_extensions_hash","value":"7300c23f4e6fa34e534fc99c1b628588"},{"key":"webgl_renderer","value":"WebKit WebGL"},{"key":"webgl_vendor","value":"WebKit"},{"key":"webgl_version","value":"WebGL 1.0 (OpenGL ES 2.0 Chromium)"},{"key":"webgl_shading_language_version","value":"WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)"},{"key":"webgl_aliased_line_width_range","value":"[1, 1]"},{"key":"webgl_aliased_point_size_range","value":"[1, 1024]"},{"key":"webgl_antialiasing","value":"yes"},{"key":"webgl_bits","value":"8,8,24,8,8,0"},{"key":"webgl_max_params","value":"16,32,16384,1024,16384,16,16384,30,16,16,4095"},{"key":"webgl_max_viewport_dims","value":"[32767, 32767]"},{"key":"webgl_unmasked_vendor","value":"Google Inc. (NVIDIA)"},{"key":"webgl_unmasked_renderer","value":"ANGLE (NVIDIA, NVIDIA GeForce RTX 2060 (0x00001F08) Direct3D11 vs_5_0 ps_5_0, D3D11)"},{"key":"webgl_vsf_params","value":"23,127,127,23,127,127,23,127,127"},{"key":"webgl_vsi_params","value":"0,31,30,0,31,30,0,31,30"},{"key":"webgl_fsf_params","value":"23,127,127,23,127,127,23,127,127"},{"key":"webgl_fsi_params","value":"0,31,30,0,31,30,0,31,30"},{"key":"webgl_hash_webgl","value":"89f3265915d19d097c9f67ed49c1f46d"},{"key":"user_agent_data_brands","value":"Google Chrome,Chromium,Not/A)Brand"},{"key":"user_agent_data_mobile","value":false},{"key":"navigator_connection_downlink","value":0.75},{"key":"navigator_connection_downlink_max","value":null},{"key":"network_info_rtt","value":500},{"key":"network_info_save_data","value":false},{"key":"network_info_rtt_type","value":null},{"key":"screen_pixel_depth","value":24},{"key":"navigator_device_memory","value":8},{"key":"navigator_pdf_viewer_enabled","value":true},{"key":"navigator_languages","value":"zh-CN,zh"},{"key":"window_inner_width","value":0},{"key":"window_inner_height","value":0},{"key":"window_outer_width","value":1920},{"key":"window_outer_height","value":1032},{"key":"browser_detection_firefox","value":false},{"key":"browser_detection_brave","value":false},{"key":"browser_api_checks","value":["permission_status: true","eye_dropper: true","audio_data: true","writable_stream: true","css_style_rule: true","navigator_ua: true","barcode_detector: false","display_names: true","contacts_manager: false","svg_discard_element: false","usb: defined","media_device: defined","playback_quality: true"]},{"key":"browser_object_checks","value":"554838a8451ac36cb977e719e9d6623c"},{"key":"29s83ih9","value":"68934a3e9455fa72420237eb05902327â\x81£"},{"key":"audio_codecs","value":"{\\"ogg\\":\\"probably\\",\\"mp3\\":\\"probably\\",\\"wav\\":\\"probably\\",\\"m4a\\":\\"maybe\\",\\"aac\\":\\"probably\\"}"},{"key":"audio_codecs_extended_hash","value":"805036349642e2569ec299baed02315b"},{"key":"video_codecs","value":"{\\"ogg\\":\\"\\",\\"h264\\":\\"probably\\",\\"webm\\":\\"probably\\",\\"mpeg4v\\":\\"\\",\\"mpeg4a\\":\\"\\",\\"theora\\":\\"\\"}"},{"key":"video_codecs_extended_hash","value":"67b509547efe3423d32a3a70a2553c16"},{"key":"media_query_dark_mode","value":false},{"key":"f9bf2db","value":"{\\"pc\\":\\"no-preference\\",\\"ah\\":\\"hover\\",\\"ap\\":\\"fine\\",\\"p\\":\\"fine\\",\\"h\\":\\"hover\\",\\"u\\":\\"fast\\",\\"prm\\":\\"reduce\\",\\"prt\\":\\"no-preference\\",\\"s\\":\\"enabled\\",\\"fc\\":\\"none\\"}"},{"key":"headless_browser_phantom","value":false},{"key":"headless_browser_selenium","value":false},{"key":"headless_browser_nightmare_js","value":false},{"key":"headless_browser_generic","value":4},{"key":"1l2l5234ar2","value":"1750311066787â\x81£"},{"key":"document__referrer","value":""},{"key":"window__ancestor_origins","value":["https://www.arkoselabs.com"]},{"key":"window__tree_index","value":[0]},{"key":"window__tree_structure","value":"[[]]"},{"key":"window__location_href","value":"https://client-api.arkoselabs.com/v2/2.14.0/enforcement.673c2bc2a64779bc3ca40cdf91f2a7ec.html"},{"key":"client_config__sitedata_location_href","value":"https://www.arkoselabs.com/arkose-matchkey/"},{"key":"client_config__language","value":null},{"key":"client_config__surl","value":"https://client-api.arkoselabs.com"},{"key":"c8480e29a","value":"165ee51d4a3e27bfeee660c40851de9fâ\x81¢"},{"key":"client_config__triggered_inline","value":false},{"key":"mobile_sdk__is_sdk","value":false},{"key":"audio_fingerprint","value":"124.04347527516074"},{"key":"navigator_battery_charging","value":true},{"key":"media_device_kinds","value":null},{"key":"media_devices_hash","value":null},{"key":"navigator_permissions_hash","value":"67419471976a14a1430378465782c62d"},{"key":"math_fingerprint","value":"0ce80c69b75667d69baedc0a70c82da7"},{"key":"supported_math_functions","value":"67d1759d7e92844d98045708c0a91c2f"},{"key":"screen_orientation","value":"landscape-primary"},{"key":"rtc_peer_connection","value":5},{"key":"4b4b269e68","value":"39a6fa63-c69f-458f-a9a6-2f9f27757dd6"},{"key":"6a62b2a558","value":"673c2bc2a64779bc3ca40cdf91f2a7ec"},{"key":"is_keyless","value":false},{"key":"c2d2015","value":"29d13b1af8803cb86c2697345d7ea9eb"},{"key":"43f2d94","value":false},{"key":"20c15922","value":true},{"key":"4f59ca8","value":null},{"key":"3ea7194","value":{"supported":true,"formats":["HDR10","HLG"],"isHDR":false}},{"key":"05d3d24","value":"ab77dc7ca26f868960ff6340cce29973"},{"key":"speech_default_voice","value":"Google Deutsch || de-DE"},{"key":"speech_voices_hash","value":"a0c90ca98043f0489c1e731e233b937e"},{"key":"83eb055","value":false},{"key":"4ca87df3d1","value":"MTI1MTczLDAsMTI4Niw1MjQ7MTI1MTk3LDAsMTM5Miw1MDA7MTI1MjE0LDAsMTUyMSw0OTA7MTI1MzgwLDAsMTQ1Niw1NjY7MTI1Mzk3LDAsMTI3MCw2MTQ7MTI1NDE0LDAsMTE3NSw2NDM7MTI1NDMwLDAsMTEwNyw2NTU7MTI1NDM5LDAsMTA4OSw2NjE7MTI1OTE4LDAsNzQwLDEyNjsxMjU5MjUsMCw3NTAsMTA2OzEyNTkzMiwwLDc2Myw4MjsxMjU5NDEsMCw3NzEsNzI7MTI1OTUwLDAsNzc4LDYxOzEyNTk1NiwwLDc4Myw1NTsxMjYwMTQsMCw3ODgsNjU7MTI2MDIyLDAsNzg5LDcxOzEyNjAzNywwLDc4OSw4MTsxMjYwNTMsMCw3ODksODk7MTI2MDYwLDAsNzkzLDk5OzEyNjA2OSwwLDc5NSwxMDg7MTI2MDc2LDAsNzk5LDExNzsxMjYwODUsMCw4MDMsMTI2OzEyNjA5MywwLDgwOSwxMzY7MTI2MTA3LDAsODE3LDE0NjsxMjcyMjIsMCw4NTQsNTQ3OzEyNzIyOCwwLDg0Nyw1Mzk7MTI3MjM2LDAsODQxLDUzMjsxMjcyNDUsMCw4MzQsNTIyOzEyNzI1MywwLDgyNiw1MTM7MTI3MjY5LDAsODE1LDUwMDsxMjcyNzcsMCw4MTAsNDkwOzEyNzI4NSwwLDgwNiw0ODQ7MTI3MjkzLDAsODAxLDQ3NDsxMjczMDEsMCw3OTksNDY2OzEyNzMwOCwwLDc5Nyw0NjE7MTI3MzE3LDAsNzk1LDQ1NjsxMjczMzQsMCw3OTUsNDUwOzEyNzM3MiwwLDc5NSw0NDM7MTI3NDQ0LDAsNzk4LDQzNzsxMjc1MTcsMCw4MDIsNDMzOzEyNzU0MiwxLDgwMiw0MzM7MTI3NjIxLDIsODAyLDQzMzs="},{"key":"867e25e5d4","value":"Ow=="},{"key":"d4a306884c","value":"MTI1MDY0LDAsMTQ7MTI1MTQwLDEsMTQ7"}]},{"key":"fe","value":["DNT:unknown","L:zh-CN","D:24","PR:1","S:1920,1080","AS:1920,1032","TO:-480","SS:true","LS:true","IDB:true","B:false","ODB:false","CPUC:unknown","PK:Win32","CFP:-642173219","FR:false","FOS:false","FB:false","JSF:Arial,Arial Black,Arial Narrow,Book Antiqua,Bookman Old Style,Calibri,Cambria,Cambria Math,Century,Century Gothic,Century Schoolbook,Comic Sans MS,Consolas,Courier,Courier New,Garamond,Georgia,Helvetica,Impact,Lucida Bright,Lucida Calligraphy,Lucida Console,Lucida Fax,Lucida Handwriting,Lucida Sans,Lucida Sans Typewriter,Lucida Sans Unicode,Microsoft Sans Serif,Monotype Corsiva,MS Gothic,MS PGothic,MS Reference Sans Serif,MS Sans Serif,MS Serif,Palatino Linotype,Segoe Print,Segoe Script,Segoe UI,Segoe UI Light,Segoe UI Semibold,Segoe UI Symbol,Tahoma,Times,Times New Roman,Trebuchet MS,Verdana,Wingdings,Wingdings 2,Wingdings 3","P:Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,PDF Viewer,WebKit built-in PDF","T:0,false,false","H:12","SWF:false"]},{"key":"ife_hash","value":"8979c33a31ba3c31d9f47c0571e35fa9"},{"key":"jsbd","value":"{\\"HL\\":2,\\"NCE\\":true,\\"DT\\":\\"\\",\\"NWD\\":\\"false\\",\\"DMTO\\":1,\\"DOTO\\":1}"}]'
keys = Buffer.from(dn(m,hexB));
ivs = Buffer.from(b2);
// console.log(aesEncrypt(data, keys, ivs));

const datas = JSON.stringify({
ct:aesEncrypt(data, keys, ivs).encrypted,
s:bytesToHexString(b),
iv:aesEncrypt(data, keys, ivs).iv
})

const datasBase64 = Buffer.from(datas).toString('base64');

console.log("\nBase64编码后的数据:", datasBase64);

注意事项

最后s:bytesToHexString(b)加上之后base64下