HTML 5 Canvas指紋および逆追跡の紹介


1 Canvas指紋の概要
多くのサイトはCanvas指紋でユーザーを追跡しています.browserleaks[1]はcanvas指紋をオンラインで検出するサイトです.一般的な指紋実装原理は、canvasキャンバスによっていくつかの図形を描画し、いくつかの文字を記入し、その後、図形のbase 64符号化を取得し、hashを経て最終的な指紋を得ることである.
次の簡単な例では、最終的にtoDataUrlを呼び出すと符号化が生成されます.
  var getCanvasFp = function (options) {
    var result = []
    // Very simple now, need to make it more complex (geo shapes etc)
    var canvas = document.createElement('canvas')
    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
    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()) }
    return result
  }

2追跡防止
1の紹介では,追跡されないように生成を調整し,自分のデータが露出しないようにする必要がある.色の変換、透明度、フォントなど、変化の形式はたくさんあります.さらにcanvasはgetImageData[2]を提供して1つのグラフィックの画素データを得、ここでのデータを変化させても結果を変化させることができる.ここでanticanvas[3]を例にとると、他の処理方法の原理は類似している.次のサンプルコードの原理は簡単で、元の方法をブロックすることによって現在の結果を変更することです.符号化では、元の方法を閉パケット[4]で保存する.最終的にエージェントの効果を実現し、元のメソッドが呼び出される前にパラメータを変更します.
(function(){
    CanvasRenderingContext2D.prototype.getImageData = function(a) {
      return function() {
        console.log("Context");
        spoofFromContext(this,a);
        return a.apply(this, arguments);
      };
    }(CanvasRenderingContext2D.prototype.getImageData);
    HTMLCanvasElement.prototype.toDataURL=(function(){
        var original = HTMLCanvasElement.prototype.toDataURL;
        return function() {
            spoof(this);
            return original.apply(this,arguments);
        };
    })();
    function spoof(canvas){
        	var ctx = canvas.getContext("2d");
            spoofFromContext(ctx);    
    }
    function spoofFromContext(ctx,a){        
        	if(!a) a = ctx.getImageData;
 			var data = a.call(ctx,0, 0, ctx.canvas.width, ctx.canvas.height);
            for(var c=0; c<data.data.length; c=c+4){
                var r = data.data[c];
                var g = data.data[c+1];
                var b = data.data[c+2];
                var a = data.data[c+3];
                if(a!=0){
                    data.data[c]=r-Math.random();
                    data.data[c+1]=g-Math.random();
                    data.data[c+2]=b-Math.random();
                    data.data[c+3]=a-Math.random();
                }                               
         	}   
            ctx.putImageData(data, 0, 0);   
            console.log("Spoofed");     
    } 
})();

3参考
[1].canvas指紋、https://browserleaks.com/canvas#how-does-it-work [2].getImageData使用概要https://blog.csdn.net/FE_dev/article/details/82586698 [3].anticanvas,https://github.com/WolfspiritM/AntiCF/blob/master/anticanvas.js [4].JSクローズhttp://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html