Canvas帆布指纹识别技术和 Fingerprinting的使用

在过去,实现上述 Cookie 是最受欢迎的一种。但由于移动互联网的发展,移动设备限制、用户禁用 Cookie。使得 Cookie 愈来愈不受待见。 伴随着 HTML5 的成熟,通过 Canvasfingerprintjs 技术标识一个唯一的浏览器逐渐被接受。它的特点是不通过 Cookie,用户基本无法屏蔽它 。

不废话上代码:

<html>
    <body>
        <div id="myCanvas"></div>
    </body>
    <script>
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var txt = 'http://security.tencent.com/';
        ctx.textBaseline = "top";
        ctx.font = "14px 'Arial'";
        ctx.textBaseline = "tencent";
        ctx.fillStyle = "#f60";
        ctx.fillRect(125,1,62,20);
        ctx.fillStyle = "#069";
        ctx.fillText(txt, 2, 15);
        ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
        ctx.fillText(txt, 4, 17);
        
        var d=document.getElementById("myCanvas");
        d.appendChild(canvas)

        var b64 = canvas.toDataURL().replace("data:image/png;base64,","");
        var bin = atob(b64);
        console.log(bin)
        var crc = bin2hex(bin.slice(-16,-12));
        console.log(crc);
        // 输出crc码,crc在一定程度上标识了浏览器的唯一性,但是,在相同设备,
        // 相同浏览器上,重复特别严重。(该指纹能够识别出了某种GPU在安装了某种字体下的群体。)
        
        function bin2hex(str) {
            var result = "";
            for (i = 0; i < str.length; i++ ) {
            var c = str.charCodeAt(i);
            result += byte2Hex(c>>8 & 0xff); // 高字节
            result += byte2Hex(c & 0xff);// 低字节
            }
            return result;
        }
         
        function byte2Hex(b) {
            if(b < 0x10)
            return "0" + b.toString(16);
            else
            return b.toString(16);
        }

    </script>
</html>

其实现原理:
获取绘画的内容,需要使用到 canvas.toDataURL()方法,该方法返回的是图片内容的 base64 编码字符串。对于 PNG 文件格式,以块 chunk划分,最后一块是一段 32 位的 CRC校验,提取这段 CRC校验码便可以用于用户的唯一标识,通过验证,CRC 在一定程度上标识了浏览器的唯一性,
缺陷:在相同设备,相同浏览器上,重复特别严重。

国外有一个经过优化后的表示浏览器的唯一性的 JavaScript 库,fingerprintJS

  • 1.它除了利用 Canvas 以外,还加入了其它的影响因素,这些因素包括

  • 2.浏览器http请求中的用户代理-navigator.userAgent

  • 3.浏览器的语言(中文、英文……)-navigator.language

  • 4.设备屏幕的色彩信息-screen.colorDepth

  • 5.设备屏幕的宽高-screen.height screen.width

  • 6.格林威治时间和本地时间之间的时差-Date().getTimezoneOffset()

  • 7.是否支持sessionStorage-window.sessionStorage

  • 8.是否支持localStorage-window.localStorage

  • 9.是否支持indexdDB-window.indexedDB

  • 10.是否支持-docment.body.addBehavior(IE5的一个属性)

  • 11.是否支持调用本地数据库-window.openDatabase

  • 12.浏览器所在系统的CPU等级-navigator.cupClass

  • 13.客户端的操作系统-navigator.platform

  • 14.是否支持Do not track功能-navigator.doNotTrack

  • 15.获取浏览器部分插件信息-flash plugin、Adobe PDF reader、QuickTime、real players、ShockWave player、Windows media player、Silverlight、Skype

  • 16.Canvas 指纹
    据说该标识精准度达90%以上

实现源码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Fingerprint2 TEST</title>
    <style>
        body {
            color: #555;
        }
        #info {
            font-size: 12px;
        }
        #control span {
            color: #333;
            margin-left: 10px;
        }
    </style>
</head>
<body>
<div id="info">
    <p>Fingerprint2 Github: <a href="https://github.com/Valve/fingerprintjs2" target="_blank">https://github.com/Valve/fingerprintjs2</a>
    </p>
    <p>纯前端实现的浏览器指纹采集器,通过获取浏览器中所有能获取到的信息(部分通过base64转成String),最后生成出md5,用于该用户在该设备上的唯一标识码,官方宣称准确度高达99.5%</p>
</div>
<div id="control">
    <button onclick="start()">开始</button>
    <span>userAgent:</span><input type="checkbox" id="userAgent" checked="checked">
    <span>fonts:</span><input type="checkbox" id="fonts" checked="checked">
    <span>fontsFlash:</span><input type="checkbox" id="fontsFlash" checked="checked">
    <span>canvas:</span><input type="checkbox" id="canvas" checked="checked">
    <span>webgl:</span><input type="checkbox" id="webgl" checked="checked">
    <span>audio:</span><input type="checkbox" id="audio" checked="checked">
    <span>enumerateDevices:</span><input type="checkbox" id="enumerateDevices" checked="checked">
</div>
<div id="view">
</div>
<script src="https://cdn.staticfile.org/fingerprintjs2/2.1.0/fingerprint2.min.js"></script>
<script>
    function start() {
        const start = new Date().getTime();
        let view = document.querySelector('#view');
        view.innerHTML = '';
        let excludes = {};
        if (!document.querySelector('#userAgent').checked) {
            excludes.userAgent = true;
        }
        if (!document.querySelector('#audio').checked) {
            excludes.audio = true;
        }
        if (!document.querySelector('#enumerateDevices').checked) {
            excludes.enumerateDevices = true;
        }
        if (!document.querySelector('#fonts').checked) {
            excludes.fonts = true;
        }
        if (!document.querySelector('#fontsFlash').checked) {
            excludes.fontsFlash = true;
        }
        if (!document.querySelector('#webgl').checked) {
            excludes.webgl = true;
        }
        if (!document.querySelector('#canvas').checked) {
            excludes.canvas = true;
        }
        let options = {excludes: excludes}

        Fingerprint2.get(options, function (components) {
            // 参数
            const values = components.map(function (component) {
                return component.value
            });
            // 指纹
            console.log(values.join(''))
            const murmur = Fingerprint2.x64hash128(values.join(''), 31);
            view.innerHTML += '<p>指纹 : ' + murmur + '</p>';
            view.innerHTML += '<p>消耗 : ' + (new Date().getTime() - start) + ' 毫秒</p>';
            view.innerHTML += '<p>使用的参数 : </p>';
            for (const c of components) {
                view.innerHTML += '<p>' + c.key + ' : ' + c.value + '</p>';
            }
        });
    }
</script>
</body>
</html>

总结:
Canvas 指纹只能作为一参考属性去判断设备的唯一性,不能只用这一个因素来判定设备唯一性。FingerPrint.js也不能取代 Cookie,但是可以作为辅助,如果用户清除了 Cookie 的情况下,还可以通过 FingerPrint.js 跟踪到该用户重新 Set Cookie

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,504评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,898评论 1 300
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,218评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,322评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,693评论 3 290
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,812评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,747评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,476评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,700评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,190评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,541评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,206评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,129评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,903评论 0 199
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,894评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,748评论 2 274

推荐阅读更多精彩内容