赞
踩
async function sha256(message) { // 把字符串转换为Uint8Array const msgBuffer = new TextEncoder().encode(message); // 计算散列值 const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); // 转换为数组 const hashArray = Array.from(new Uint8Array(hashBuffer)); // 转换为16进制字符串 const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); return hashHex; } function getWebGLFingerprint() { // 尝试创建一个canvas元素并获取WebGL渲染上下文 const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) { // 如果无法获取到WebGL上下文,则无法生成指纹 return null; } // 创建一个可以用来生成指纹的函数 const getGlParam = function(parameter) { // WebGL参数值可以通过调用gl.getParameter()获取 const value = gl.getParameter(parameter); return value ? value.toString() : 'null'; }; // 收集一系列WebGL参数的值 const webglParams = [ // 表示GPU驱动和硬件的字符串 gl.VENDOR, gl.RENDERER, // WebGL版本字符串 gl.VERSION, // 支持的WebGL扩展列表 gl.getSupportedExtensions(), // 其他一些可能影响指纹的特性 gl.MAX_TEXTURE_SIZE, gl.MAX_RENDERBUFFER_SIZE, // ...可以根据需要获取更多的参数 ]; // 遍历并收集参数值 const glValues = webglParams.map(param => { if (Array.isArray(param)) { return param.join('-'); } return getGlParam(param); }); // 拼接得到的参数值作为一个长字符串,这就是我们的WebGL指纹 const webglFingerprint = glValues.join('_'); return webglFingerprint; } sha256(getWebGLFingerprint()).then(hash => console.log(hash));
dfe89f41416faecf0ab4be2ddeccdc79999aafd3577a0e14e9b3e5265e72d6e7
注意:这里是全网独一份。
third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
#include
后面)#include <algorithm> // std::shuffle
#include <random> // std::default_random_engine
#include <chrono> // std::chrono::system_clock
std::optional<Vector<String>>
WebGLRenderingContextBase::getSupportedExtensions() {
if (isContextLost())
return std::nullopt;
Vector<String> result;
for (ExtensionTracker* tracker : extensions_) {
if (ExtensionSupportedAndAllowed(tracker)) {
result.push_back(tracker->ExtensionName());
}
}
return result;
}
std::optional<Vector<String>> WebGLRenderingContextBase::getSupportedExtensions() { if (isContextLost()) return std::nullopt; Vector<String> result; for (ExtensionTracker* tracker : extensions_) { if (ExtensionSupportedAndAllowed(tracker)) { result.push_back(tracker->ExtensionName()); } } // 使用当前时间作为随机数生成的种子 unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine engine(seed); // 打乱result中的元素顺序 std::shuffle(result.begin(), result.end(), engine); return result; }
可以看到,获取webGL指纹的关键函数就是
getSupportedExtensions
,返回当前WebGL上下文对象支持的所有扩展名称的列表。
我们将返回列表打乱随机,js收集的指纹信息hash自然每次都不一样啦。
不知道后续还有没有人关注
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。