生成设备指纹的目的是为了能唯一地标识设备,而且这个标识在设备的生命周期内保持稳定。因此,在选择设备特征时,通常需要考虑这些特征的唯一性和稳定性。
- 软件及配置信息一版不适合,是因为这类变化虽然不大,但万一变化后,设备指纹会变,影响使用。比如:
- 操作系统信息:操作系统版本、安装日期、系统语言、系统时区等。
- 配置信息:网络连接类型(WiFi或以太网)、网络运营商、屏幕分辨率、安装的字体、安装的应用程序等。
- 硬件信息不容易变化,是我们生成设备指纹的首选。比如:
- CPU型号、硬盘序列号、内存大小、图形处理器(GPU)信息、MAC地址等。
MAC地址做设备指纹的好处
基于网卡地址(MAC地址)做设备指纹的好处:
唯一性:
MAC地址通常在生产时就被硬编码到设备中,并且全世界范围内唯一。这使得它能作为一个很好的设备标识符。
易于获取:
在大多数操作系统中,都有相对简单的方式来获取MAC地址。
稳定性:
与IP地址相比,MAC地址不会因设备在网络中的位置变化而改变,除非用户手动修改或网络适配器被更换。
MAC地址做设备指纹的局限性
但它也有局限性:
用户可修改:
虽然MAC地址通常在硬件中硬编码,但在许多操作系统中,用户可以更改设备的MAC地址。如果用户更改了MAC地址,那么基于MAC地址的设备指纹就会改变。
设备有多个网卡:
如果一个设备有多个网络接口(例如,有线和无线),那么每个网络接口都会有一个不同的MAC地址。这可能会给基于MAC地址生成设备指纹带来困扰。比如要考虑下面问题:
- 顺序问题,前后顺序是否会影响最终生成的指纹?
- 多个哪些启用了,哪些没启用,需要考虑;
- 多个里面的虚拟网卡地址变化的概率要大很多;
隐私和安全问题:
MAC地址可以用来追踪设备,这可能引发隐私和安全问题。为了避免这种情况,一些设备和操作系统提供了“MAC地址随机化”功能,这可能会影响基于MAC地址的设备指纹。
虚拟机和容器:
虚拟机和容器通常有自己的虚拟网络接口和MAC地址。这可能会干扰基于MAC地址的设备指纹。
总结
虽然基于MAC地址的设备指纹有一些局限性要考虑,但综合考虑,在大多数场景下,我们可以忽略这些。
常见问题
MAC地址可变性的应对方案
如果MAC地址可变,那么可能需要考虑使用其他更稳定、不易变化的设备特征。例如,设备的硬件配置(如CPU型号、硬盘序列号等)、操作系统信息(如操作系统版本、安装日期等)、设备配置(如屏幕分辨率、安装的字体等)等,这些信息通常比MAC地址更稳定,不容易被修改。
另外,也可以考虑使用一些复杂的设备指纹技术,这些技术通常会考虑设备的行为特性(如鼠标移动模式、键盘输入模式等)。这种方式可以在一定程度上抵抗设备特征的变化,但可能需要收集更多的数据,并可能面临更大的隐私和安全挑战。
需要注意的是,生成设备指纹并不是一个完美的解决方案,它总是在唯一性、稳定性、隐私和安全之间寻找平衡。在实际应用中,可能需要结合多种方法,并根据具体的需求和约束进行调整。
使用多种信息组合设备指纹的问题
使用多种信息进行设备指纹的生成,可能会碰到下面问题:
- 增加指纹变化的风险:参与方越多,指纹越容易发生变化。
- 隐私问题:设备指纹收集的信息越多,可能对用户的隐私侵入也越严重。这可能会引发用户的反感,也可能触犯某些地区的隐私法规。
- 兼容性问题:不同的设备或操作系统可能提供不同的信息,或者以不同的方式提供信息。如果设备指纹依赖于某些特定的信息或获取方式,可能会导致兼容性问题。
- 性能问题:获取设备信息需要时间和资源,特别是如果需要收集大量或复杂的信息时。这可能会影响设备的性能或用户的体验。
因此,生成设备指纹需要权衡各种因素,包括唯一性、稳定性、隐私、兼容性、性能和安全等。在实际应用中,可能需要根据具体的需求和约束来调整和优化设备指纹的生成方法。
Python 获得MAC地址
在第一个方法(使用uuid模块)无法获取MAC地址时,执行命令行获得。
import platform
import subprocess
def get_mac():
try:
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
return ":".join([mac[e:e+2] for e in range(0, 11, 2)])
except:
mac = None
system = platform.system()
if system in ["Linux", "Darwin"]:
try:
output = subprocess.check_output("ifconfig", shell=True).decode("utf-8")
lines = output.splitlines()
for line in lines:
if "ether" in line:
mac = line.split("ether")[1].strip().split()[0]
break
except subprocess.CalledProcessError:
pass
elif system == "Windows":
try:
output = subprocess.check_output("ipconfig /all", shell=True).decode("utf-8")
lines = output.splitlines()
start = False
for line in lines:
if line.strip().endswith('WLAN:'):
start = True
if (line.lstrip().startswith("Physical Address") or line.lstrip().startswith("物理地址")) and start:
mac = line.split(":")[1].strip().replace("-", ":").lower()
break
except subprocess.CalledProcessError:
pass
return mac
Python 获得硬盘序列号
在Windows中,你可以使用pywin32库,它提供了访问Windows API的接口。你可以使用Win32_DiskDrive WMI类来获取硬盘序列号:
import win32api
import win32file
import pywintypes
import os
def get_hdd_serial_number(drive):
try:
vol_name, vol_serial_num, vol_type, vol_flag = win32api.GetVolumeInformation(drive + ":\\")
return str(vol_serial_num)
except:
return None
# Get serial number of C drive
print(get_hdd_serial_number('C'))
这将返回C驱动器的序列号。
在Linux中,硬盘信息通常存储在/dev/disk/by-id/目录下。你可以使用标准的文件操作函数来获取这些信息:
import os
def get_hdd_serial_number():
# This assumes the primary HDD is sda, adjust if necessary
hdd_info = os.popen('ls -l /dev/disk/by-id/').read()
print(hdd_info)
get_hdd_serial_number()
这将输出所有硬盘的详细信息,你可以在其中查找你需要的硬盘序列号。
请注意,获取硬盘序列号可能需要特定的权限,而且可能受到隐私和安全规定的限制。在实际使用时,需要确保你的操作符合相关法律和政策。
标签:优缺点,地址,指纹,网卡,MAC,信息,line,设备 From: https://www.cnblogs.com/ghj1976/p/ji-yu-wang-ka-de-zhi-zuo-she-bei-zhi-wen-de-you-qu.html