JavaScript Tricks: Device Fingerprint
Tags: javascript, fingerprint, webdev
Published: 2023-12-15 00:25:52

Device fingerprinting, usually refers to browser device fingerprinting, which can identify whether it is the same visitor by obtaining feature information from the browser.

Fingerprint information is usually obtained from several dimensions, such as navigator, window, screen.
Example, navigator information.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n10rwmbe1bf7s1xbhxku.png)

Among these information, there are some special, fixed data that can be used to identify the characteristics of the user's system, such as: operating system type, language, browser name, browser plug-in, screen resolution, screen size, CPU number, time zone, whether the screen supports touch control, whether it supports cookies, whether it supports local storage, whether it supports WebGL, and so on.

The collection of these data forms the unique characteristics of the device, just like a person's fingerprint, which can be used to identify a device. As shown in the figure below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1o45opzsi6evlylnmhw.png)

Note: The accuracy of fingerprint recognition depends on the data source selected for recognition, but the more data sources, the better. Too many or too few data sources can easily lead to false positives. Usually, after extensive testing, suitable data items are selected. For demonstration purposes in this article, only a small number of data sources are used.

At this point, the fingerprint data has been obtained, but the content is too much to identify the device by comparing the fingerprints. Usually, further processing is performed on the data, such as performing md5 hashing to form a string feature code.

Of course, other algorithms can also be used. Here, a simple custom algorithm is used to obtain features.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zta8mslzvv361r1q7spc.png)

## Source

```
<html>
<script>
	//获取浏览器指纹
	function get_fingerprint(){

		var fingerprint = [];
        //用户代理
		fingerprint.push({key: "user_agent", value: navigator.userAgent });
        //语言
		fingerprint.push({key: "language", value: navigator.language});
		//设备像素比：物理像素和设备独立像素的比例
		fingerprint.push({key: "pixel_ratio", value: window.devicePixelRatio });
        //硬件并发数，即：几核CPU
		fingerprint.push({key: "hardware_concurrency", value: navigator.hardwareConcurrency });
        //屏幕的宽度、高度
		fingerprint.push({key: "resolution", value: [screen.width, screen.height] });
        //屏幕分辨率的高、宽
		fingerprint.push({key: "available_resolution", value: [screen.availHeight, screen.availWidth] });
        //格林威治时间与本地时间的差值，单位是分钟
		fingerprint.push({key: "timezone_offset", value: new Date().getTimezoneOffset() });
		//本地存储支持度识别，例：window.openDatabase被IE、Google Chrome支持、但FireFox不支持
		fingerprint.push({key: "session_storage", value: !window.sessionStorage });
		fingerprint.push({key: "local_storage", value: !window.localStorage });
		fingerprint.push({key: "indexed_db", value: !window.indexedDB });
		fingerprint.push({key: "open_database", value: !window.openDatabase });
	    //系统平台类型，如:win32
		fingerprint.push({key: "navigator_platform", value: navigator.platform });
		//系统类型及版，如：Windows NT 10.0; Win64; x64
		fingerprint.push({key: "navigator_oscpu", value: navigator.oscpu });
		//浏览器是否开启隐私保护
		fingerprint.push({key: "do_not_track", value: navigator.doNotTrack });
		//屏幕是否支持触摸
		fingerprint.push({key: "touch_support", value: navigator.maxTouchPoints });
		//浏览器插件
		for(i=0; i<navigator.plugins.length;i ++){
			fingerprint.push({key: "navigator_plugin_" + i, value: navigator.plugins[i].name });
		}
		//是否支持cookie
		fingerprint.push({key: "cookie_enabled", value: navigator.cookieEnabled });

		console.log(fingerprint);

		//简化指纹
		var short_fingerprint = "";
		for(j=0; j<fingerprint.length; j++){
			short_fingerprint += fingerprint[j].value.toString().toLowerCase().substring(0,1);
		}
		short_fingerprint += fingerprint.length;
		short_fingerprint += navigator.plugins.length;
		console.log("设备指纹：",short_fingerprint)
	}
	get_fingerprint();
</script>
</html>
```

## Execute

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9oecxhl3banmi5yye4j.png)

Device fingerprinting is mainly used for login-free verification and identification of unfamiliar users, such as determining the number of visits of a visiting customer, the number of pages visited, whether they clicked on products or advertisements, whether they placed an order, which page they exited from, whether they performed dangerous operations, and so on.

Sometimes, some visitors who understand technology or have their own purposes do not want to be identified, so they may analyze the fingerprint source by viewing the JS source code in the webpage and modify the fingerprint source data accordingly to avoid identification. In order to prevent this situation, there are usually two methods:

Firstly, on the front end, the JS code that implements the fingerprint function is encrypted and obfuscated using JShaman JavaScript Obfuscator to prevent analysis. At the same time, the fingerprint data can be sent to the back end for further determination.

Secondly, on the backend, after receiving the fingerprints from the front end, it can be determined how many fingerprints are matched, such as 80% or 90%. Then it can be guessed that some data may have been modified. Moreover, combined with the "backend fingerprints", such as the visitor's IP address, cookie, etc., it can conduct a second fingerprint identification.