问题描述
最近在研究设备指纹,看到现下比较靠谱的是canvas指纹,能够忽略无痕模式的影响,保证浏览器指纹的稳定性,于是想尝试一下。但是尝试了一下发现chrome,IE10,Edge,Firefox,Opera
在正常模式和无痕模式下,设备指纹都是一致的,唯独safari有点不同,无痕模式下不管怎么刷新,指纹D
都是保持不变,而在正常模式下,有一定概率第一次生成的指纹A
和刷新页面后第二次生成的B
不一致,同时再次反复刷新,生成的指纹C
和B/D
是始终保持一致的。
我就很费解了同一台设备,同一个浏览器,同样的canvas图和操作为什么会有这样刷新页面就会变的操作。检查了一下输出后发现,在safari用canvas.toDataURL()
生成的canvas的base64
字符串会变。就闹不明白了这是为什么,跪求大佬们指点迷津。。。
问题截图
第一次
第二次
可以看到是截取的最后几位dataURL发生了变化所以加密的时候出了问题
测试代码
<!DOCTYPE html>
<html>
<body>
<style>
html {
font-family: Arail;
}
</style>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>
<canvas id="drawing" width=" 200" height="200"
>A drawing of something.</canvas
>
<script>
var canvasFP1 = '';
var canvasFP2 = '';
function bin2hex(s) {
console.log('inner bin2hex', s);
var i,
l,
o = '',
n;
s += '';
for (i = 0, l = s.length; i < l; i++) {
n = s.charCodeAt(i).toString(16);
o += n.length < 2 ? '0' + n : n;
}
return o;
}
function hashstr(s) {
console.log('inner hashstr', s);
var hash = 0;
if (s.length == 0) return hash;
for (i = 0; i < s.length; i++) {
// console.log(i, s.charCodeAt(i));
char = s.charCodeAt(i);
hash = (hash << 5) - hash + char;
// console.log(i, hash);
hash = hash & hash; // Convert to 32bit integer
// console.log(i, 'hash2', hash);
}
return hash;
}
function FPjs() {
var result = [];
// Very simple now, need to make it more complex (geo shapes etc)
var canvas = document.getElementById('drawing');
canvas.width = 2000;
canvas.height = 200;
canvas.style.display = 'inline';
var ctx = canvas.getContext('2d');
// detect browser support of canvas winding
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js
ctx.rect(0, 0, 10, 10);
ctx.rect(2, 2, 6, 6);
result.push(
'canvas winding:' +
(ctx.isPointInPath(5, 5, 'evenodd') === false
? 'yes'
: 'no'),
);
ctx.textBaseline = 'alphabetic';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
// https://github.com/Valve/fingerprintjs2/issues/66
ctx.font = '11pt Arial';
// if (options.dontUseFakeFontInCanvas) {
// ctx.font = '11pt Arial';
// } else {
// ctx.font = '11pt no-real-font-123';
// }
ctx.fillText(
'Cwm fjordbank glyphs vext quiz, \ud83d\ude03',
2,
15,
);
ctx.fillStyle = 'rgba(102, 204, 0, 0.2)';
ctx.font = '18pt Arial';
ctx.fillText(
'Cwm fjordbank glyphs vext quiz, \ud83d\ude03',
4,
45,
);
// canvas blending
// http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
// http://jsfiddle.net/NDYV8/16/
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = 'rgb(255,0,255)';
ctx.beginPath();
ctx.arc(50, 50, 50, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.fillStyle = 'rgb(0,255,255)';
ctx.beginPath();
ctx.arc(100, 50, 50, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.fillStyle = 'rgb(255,255,0)';
ctx.beginPath();
ctx.arc(75, 100, 50, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.fillStyle = 'rgb(255,0,255)';
// canvas winding
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
// http://jsfiddle.net/NDYV8/19/
ctx.arc(75, 75, 75, 0, Math.PI * 2, true);
ctx.arc(75, 75, 25, 0, Math.PI * 2, true);
ctx.fill('evenodd');
if (canvas.toDataURL) {
result.push(
'canvas fp:' + canvas.toDataURL('image/jpeg', 0.5),
);
}
var tempStr = result[1].slice(-16, -1);
var result11 = hashstr(tempStr);
var result22 = hashstr(result.join(','));
var result1 = document.getElementById('result1');
result1.innerHTML = 'canvasFP1 is : ' + result11;
var result2 = document.getElementById('result2');
result2.innerHTML = 'canvasFP2 is : ' + result22;
if (localStorage.getItem('result')) {
localStorage.setItem('new_result', result[1]);
console.log(
'is different',
localStorage.getItem('result') !== result[1],
);
console.log(
'new length is ',
result[1].length,
'old length is ',
localStorage.getItem('result').length,
);
} else {
localStorage.setItem('result', result[1]);
}
return result11 + '---' + result22;
}
console.log(FPjs());
</script>
</body>
</html>
忘了结帖,code没错,只是在浏览器层面,不同浏览器会对canvas指纹、webGL指纹、audio指纹添加噪声,实现反追踪,所以我们最后是通过收集其他信息,优化了策略才完成了设备指纹这一产品