指纹检测点: Math 数学库三角函数复合指纹
指纹检测点: Math 数学库三角函数复合指纹
检测了什么
在 iframe 的 window 上执行一条精心构造的三角函数复合表达式, 取 Math.atan2
的结果上报。一次采集同时探三层:
- JS 引擎数学库的数值指纹 ——
sin / cos / sqrt / atan2的浮点实现因引擎而异
(不同 libm 移植、快速近似路径、常量折叠), 差异在多层复合运算里会放大显形,
相当于"数学库版"的 canvas 指纹; - iframe 环境是否健全 —— 表达式刻意跑在
iframe.contentWindow的 Math 上,
无头环境常见的 iframe 塌陷/全局共享异常会在这里暴露
(比如 contentWindow 拿不到、Math 被主窗口代理后行为异常); - 输出形态合理性 —— 结果掺了多个
Math.random()噪声, 服务端无法精确复算,
但可以校验值域(atan2 两正参 → 0~π/2)、有限小数位、非 NaN/Infinity 等"活体"特征。
检测代码(最小化)
// 注意: 在 iframe 的 window 上执行(A = iframe.contentWindow)
function mathProbe(A) {
var Q = A.Math.SQRT2;
var m = A.Math;
var B = m.sqrt(m.abs(
m.sin(m.PI / 90 * 100 - 40 * m.random() * (m.PI / 180) / 2)
+ m.cos(100 * Q * (m.PI / 180))
* m.sin(m.PI / 180 * 40 - 100 * m.random() * (m.PI / 75) / 2)));
var C = m.random() * m.sqrt(m.abs(
1 - m.sin(40 * m.random() * (m.PI / 90) - 100 * Q * (m.PI / 180) / 2)
+ m.cos(3.7055555555555557)
* m.random()
* m.sin(m.PI / 180 * 60 - m.PI / 45 * 100 / 2)));
return m.atan2(B, C); // 上报这个角度
}
// 实际调用(采集脚本里):
// var f = document.createElement("iframe");
// document.body.appendChild(f);
// report(mathProbe(f.contentWindow));
典型输出(每次不同):
0.5521227860182784
0.3875106984325592
这个点的特点
- 掺噪声, 单值不可复算: 表达式里埋了 3 个
Math.random(), 输出每次会话必然
不同 —— 服务端验不了"这个数应该等于多少", 只能验形态。伪造者容易犯的错反而是
把值写死(每次一样)或给出 NaN; - 考的是"实现"而不是"结果": 真正的区分力藏在浮点末几位 —— 数学库不同的引擎
算同一条表达式, 尾数会漂; 这类差异无法靠 mock Math 函数轻易糊弄(包一层 Math
探针自己也能被检测到); - iframe 一石二鸟: 执行环境选在 iframe 里, 数学指纹和环境健全性一次拿到;
- 和字体枚举、CSS calc 挑战应答同属"真浏览器证明"家族, 但实现最便宜:
纯计算、零 DOM、零布局。

浙公网安备 33010602011771号