Генерация уникального идентификатора машины

Мне нужно написать функцию, которая генерирует идентификатор, который является уникальным для данной машины под управлением ОС Windows.

В настоящее время я использую WMI для запроса различных аппаратных параметров, их объединения и хеширования для получения уникального идентификатора. У меня вопрос, какие параметры мне следует использовать? В настоящее время я использую комбинацию данных bios \ cpu \ disk для создания уникального идентификатора. И я использую первый результат, если есть несколько результатов для каждой метрики.

Однако я столкнулся с проблемой, когда машина, которая выполняет двойную загрузку в 2 разных ОС Windows, генерирует разные коды сайтов на каждой ОС, что в идеале не должно происходить.

Для справки, это метрики, которые я сейчас использую:

Win32_Processor:UniqueID,ProcessorID,Name,Manufacturer,MaxClockSpeed
Win32_BIOS:Manufacturer
Win32_BIOS:SMBIOSBIOSVersion,IdentificationCode,SerialNumber,ReleaseDate,Version
Win32_DiskDrive:Model, Manufacturer, Signature, TotalHeads
Win32_BaseBoard:Model, Manufacturer, Name, SerialNumber
Win32_VideoController:DriverVersion, Name

15 ответов

Решение

Разберите SMBIOS самостоятельно и хэшируйте его произвольной длины. См. Спецификацию PDF для всех доступных структур SMBIOS.

Для запроса информации SMBIOS из Windows вы можете использовать EnumSystemFirmwareEntries, EnumSystemFirmwareTables а также GetSystemFirmwareTable,

IIRC, "уникальный идентификатор" из инструкции CPUID устарел с P3 и новее.

У меня была та же проблема, и после небольшого исследования я решил, что лучше всего будет прочитать MachineGuid в ключе реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, как предложил @Agnus. Он генерируется во время установки ОС и не изменится, если вы не сделаете другую свежую установку ОС. В зависимости от версии ОС он может содержать встроенный MAC-адрес сетевого адаптера (плюс некоторые другие числа, в том числе случайный) или псевдослучайное число, позднее для более новых версий ОС (я полагаю, что после XP SP2, но не уверен). Если это теоретически псевдослучайный, его можно подделать - если две машины имеют одинаковое начальное состояние, включая часы реального времени. На практике это будет редко, но имейте в виду, если вы ожидаете, что это будет основой для безопасности, которая может быть атакована хардкорными хакерами.

Конечно, запись в реестре также может быть легко изменена любым пользователем, чтобы подделать GUID машины, но я обнаружил, что это нарушит нормальную работу стольких компонентов Windows, что в большинстве случаев ни один обычный пользователь не сделает этого (опять же, обратите внимание для хардкорных хакеров).

С нашим инструментом лицензирования мы рассмотрим следующие компоненты

  • MAC-адрес
  • CPU (не серийный номер, а фактический профиль CPU, такой как степпинг и модель)
  • Серийный номер системного диска (не метка тома)
  • объем памяти
  • CD-ROM модель и поставщик
  • Модель и поставщик видеокарт
  • Контроллер IDE
  • SCSI контроллер

Однако вместо того, чтобы просто хэшировать компоненты и создавать систему "годен / не годен", мы создаем сопоставимый отпечаток, который можно использовать для определения различий между двумя профилями машин. Если рейтинг разности выше указанного допуска, попросите пользователя активировать снова.

За последние 8 лет использования сотен тысяч установок для конечных пользователей мы обнаружили, что эта комбинация хорошо работает для обеспечения надежного уникального идентификатора машины - даже для виртуальных машин и клонированных установок ОС.

А как насчет использования уникального идентификатора процессора?

Я ненавижу быть парнем, который говорит: "ты просто делаешь это неправильно" (я всегда ненавижу этого парня;) но...

Должен ли он генерироваться повторно для уникальной машины? Не могли бы вы просто присвоить идентификатор или сделать открытый / закрытый ключ? Может быть, если бы вы могли сгенерировать и сохранить значение, вы могли бы получить доступ к нему из обеих установок ОС на одном диске?

Вы, вероятно, изучили эти варианты, и они не работают для вас, но если нет, это то, что нужно учитывать.

Если это не вопрос доверия пользователей, вы можете просто использовать MAC-адреса.

Для одного из моих приложений я либо использую имя компьютера, если он не является доменом, либо SID учетной записи домена для компьютеров домена. Марк Руссинович рассказывает об этом в этом посте, машина SID:

Последний случай, когда дублирование SID будет проблемой, - это если распределенное приложение использует идентификаторы компьютеров для уникальной идентификации компьютеров. Никакое программное обеспечение Microsoft не делает этого, и использование идентификатора SID компьютера таким образом не работает только потому, что все контроллеры домена имеют одинаковый SID компьютера. Программное обеспечение, основанное на уникальных идентификаторах компьютеров, использует имена компьютеров или доменные SID (SID учетных записей компьютеров в Домене).

Вы можете получить доступ к SID учетной записи домена через LDAP или System.DirectoryServices,

В своей программе я сначала проверяю сервер терминалов и использую WTSClientHardwareId. В противном случае MAC-адрес локального ПК должен быть адекватным.

Если вы действительно хотите использовать список предоставленных вами свойств, оставьте такие вещи, как Name а также DriverVersion, Clockspeedи т.д., поскольку это, возможно, зависит от ОС. Попробуйте вывести одну и ту же информацию в обе операционные системы и не указывать на то, что отличается.

Вы должны изучить использование MAC-адреса на сетевой карте (если он существует). Они обычно уникальны, но могут быть изготовлены. Я использовал программное обеспечение, которое генерирует файл лицензии на основе MAC-адреса вашего сетевого адаптера, поэтому он считается довольно надежным способом различения компьютеров.

Для получения информации об оборудовании доступна библиотека: Аппаратный экстрактор серийного номера (CPU, RAM, HDD, BIOS)

Почему бы не использовать MAC-адрес вашей сетевой карты?

Можете ли вы вытащить какой-нибудь серийный номер производителя или метку обслуживания?

Наш магазин - это магазин Dell, поэтому мы используем сервисный ярлык, который уникален для каждой машины для их идентификации. Я знаю, что это можно сделать из BIOS, по крайней мере, в Linux, но я не знаю, как это сделать в Windows.

Может быть, немного обманывают, но MAC-адрес сетевого адаптера машины редко меняется без замены материнской платы в наши дни.

У меня было дополнительное ограничение, я использовал.net express, поэтому я не мог использовать стандартный аппаратный механизм запросов. Поэтому я решил использовать Power Shell для выполнения запроса. Полный код выглядит так:

Private Function GetUUID() As String
    Dim GetDiskUUID As String = "get-wmiobject Win32_ComputerSystemProduct  | Select-Object -ExpandProperty UUID"
    Dim X As String = ""
    Dim oProcess As New Process()
    Dim oStartInfo As New ProcessStartInfo("powershell.exe", GetDiskUUID)
    oStartInfo.UseShellExecute = False
    oStartInfo.RedirectStandardInput = True
    oStartInfo.RedirectStandardOutput = True
    oStartInfo.CreateNoWindow = True
    oProcess.StartInfo = oStartInfo
    oProcess.Start()
    oProcess.WaitForExit()
    X = oProcess.StandardOutput.ReadToEnd
    Return X.Trim()
End Function

Посмотрите CPUID для одного варианта. Там могут быть некоторые проблемы с многопроцессорными системами.

Попробуйте это, он дает уникальный идентификатор жесткого диска: порт DiskId32 для Delphi 7-2010.

Другие вопросы по тегам