导航

基于网卡地址做设备指纹的优缺点

Posted on 2023-06-09 15:26  蝈蝈俊  阅读(134)  评论(0编辑  收藏  举报

生成设备指纹的目的是为了能唯一地标识设备,而且这个标识在设备的生命周期内保持稳定。因此,在选择设备特征时,通常需要考虑这些特征的唯一性稳定性

  • 软件及配置信息一版不适合,是因为这类变化虽然不大,但万一变化后,设备指纹会变,影响使用。比如:
    • 操作系统信息:操作系统版本、安装日期、系统语言、系统时区等。
    • 配置信息:网络连接类型(WiFi或以太网)、网络运营商、屏幕分辨率、安装的字体、安装的应用程序等。
  • 硬件信息不容易变化,是我们生成设备指纹的首选。比如:
    • CPU型号、硬盘序列号、内存大小、图形处理器(GPU)信息、MAC地址等。

大多数场景下,我们是要在网络中区分,MAC地址就成为最常见的设备指纹选择了。

MAC地址,全称为Media Access Control Address(媒体访问控制地址),是网络设备在局域网环境中进行通信时用于识别设备的唯一标识。它通常被硬编码在设备的网络接口卡(NIC,也称为以太网卡)中,全球唯一。

MAC地址通常由12个十六进制数字(0-9和A-F)组成,以冒号(:)或连字符(-)分隔为六部分,例如:00:0A:95:9D:68:16。

MAC地址由两部分组成:

  • 前6个字符(前三组)表示厂商标识,也被称为组织唯一标识符(OUI)。这部分由全球标准化组织IEEE分配给网络设备制造商。

  • 后6个字符(后三组)是由设备制造商分配的序列号,用于识别该制造商生产的具体设备。

MAC地址做设备指纹的好处

基于网卡地址(MAC地址)做设备指纹的好处:

1、唯一性:

MAC地址通常在生产时就被硬编码到设备中,并且全世界范围内唯一。这使得它能作为一个很好的设备标识符。

2、易于获取:

在大多数操作系统中,都有相对简单的方式来获取MAC地址。

3、稳定性:

与IP地址相比,MAC地址不会因设备在网络中的位置变化而改变,除非用户手动修改或网络适配器被更换。

MAC地址做设备指纹的局限性

但它也有局限性:

1、用户可修改:

虽然MAC地址通常在硬件中硬编码,但在许多操作系统中,用户可以更改设备的MAC地址。如果用户更改了MAC地址,那么基于MAC地址的设备指纹就会改变。

2、设备有多个网卡:

如果一个设备有多个网络接口(例如,有线和无线),那么每个网络接口都会有一个不同的MAC地址。这可能会给基于MAC地址生成设备指纹带来困扰。比如要考虑下面问题:

  • 顺序问题,前后顺序是否会影响最终生成的指纹?
  • 多个哪些启用了,哪些没启用,需要考虑;
  • 多个里面的虚拟网卡地址变化的概率要大很多;

3、隐私和安全问题:

MAC地址可以用来追踪设备,这可能引发隐私和安全问题。为了避免这种情况,一些设备和操作系统提供了“MAC地址随机化”功能,这可能会影响基于MAC地址的设备指纹。

4、虚拟机和容器:

虚拟机和容器通常有自己的虚拟网络接口和MAC地址。这可能会干扰基于MAC地址的设备指纹。

总结

虽然基于MAC地址的设备指纹有一些局限性要考虑,但综合考虑,在大多数场景下,我们可以忽略这些。

常见问题

1、MAC地址可变性的应对方案

如果MAC地址可变,那么可能需要考虑使用其他更稳定、不易变化的设备特征。例如,设备的硬件配置(如CPU型号、硬盘序列号等)、操作系统信息(如操作系统版本、安装日期等)、设备配置(如屏幕分辨率、安装的字体等)等,这些信息通常比MAC地址更稳定,不容易被修改。

另外,也可以考虑使用一些复杂的设备指纹技术,这些技术通常会考虑设备的行为特性(如鼠标移动模式、键盘输入模式等)。这种方式可以在一定程度上抵抗设备特征的变化,但可能需要收集更多的数据,并可能面临更大的隐私和安全挑战。

需要注意的是,生成设备指纹并不是一个完美的解决方案,它总是在唯一性、稳定性、隐私和安全之间寻找平衡。在实际应用中,可能需要结合多种方法,并根据具体的需求和约束进行调整。

2、使用多种信息组合设备指纹的问题

使用多种信息进行设备指纹的生成,可能会碰到下面问题:

  • 增加指纹变化的风险:参与方越多,指纹越容易发生变化。
  • 隐私问题:设备指纹收集的信息越多,可能对用户的隐私侵入也越严重。这可能会引发用户的反感,也可能触犯某些地区的隐私法规。
  • 兼容性问题:不同的设备或操作系统可能提供不同的信息,或者以不同的方式提供信息。如果设备指纹依赖于某些特定的信息或获取方式,可能会导致兼容性问题。
  • 性能问题:获取设备信息需要时间和资源,特别是如果需要收集大量或复杂的信息时。这可能会影响设备的性能或用户的体验。

因此,生成设备指纹需要权衡各种因素,包括唯一性、稳定性、隐私、兼容性、性能和安全等。在实际应用中,可能需要根据具体的需求和约束来调整和优化设备指纹的生成方法。

3、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


4、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()

这将输出所有硬盘的详细信息,你可以在其中查找你需要的硬盘序列号。

请注意,获取硬盘序列号可能需要特定的权限,而且可能受到隐私和安全规定的限制。在实际使用时,需要确保你的操作符合相关法律和政策。