Gerando um ID de máquina exclusivo

Eu preciso escrever uma function que gera um id que é exclusivo para uma determinada máquina executando um sistema operacional Windows.

Atualmente, estou usando o WMI para consultar vários parâmetros de hardware e concatená-los juntos e separá-los para obter o ID exclusivo. Minha pergunta é, quais são os parâmetros sugeridos que devo usar? Atualmente, estou usando uma combinação de dados do bios \ cpu \ disk para gerar o id exclusivo. E estou usando o primeiro resultado se houver vários resultados para cada métrica.

No entanto, me deparei com um problema em que uma máquina que é inicializada em dois SOs diferentes gera códigos de sites diferentes em cada SO, o que, idealmente, não deveria acontecer.

Para referência, estas são as métricas que estou usando atualmente:

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 

    Analise o SMBIOS e faça um hash dele em um tamanho arbitrário. Veja a especificação PDF para todas as estruturas SMBIOS disponíveis.

    Para consultar as informações do SMBIOS do Windows, você pode usar EnumSystemFirmwareEntries , EnumSystemFirmwareTables e GetSystemFirmwareTable .

    IIRC, o “id único” da instrução CPUID é obsoleto do P3 e mais recente.

    Eu tive o mesmo problema e depois de uma pequena pesquisa eu decidi que o melhor seria ler MachineGuid na chave de registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography , como sugerido pela @Agnus. Ele é gerado durante a instalação do sistema operacional e não será alterado, a menos que você faça outra instalação do sistema operacional. Dependendo da versão do sistema operacional, ele pode conter o endereço MAC do adaptador de rede incorporado (além de alguns outros números, incluindo random) ou um número pseudo-random, o mais recente para versões mais recentes do sistema operacional (após o XP SP2, eu acredito, mas não tenho certeza). Se for um pseudo-random teoricamente, ele pode ser falsificado – se duas máquinas tiverem o mesmo estado inicial, incluindo o relógio de tempo real. Na prática, isso será raro, mas fique atento se você espera que seja uma base de segurança que pode ser atacada por hackers hardcore.

    É claro que uma input de registro também pode ser facilmente alterada por qualquer pessoa para forjar um GUID de máquina, mas o que eu descobri é que isso interromperia a operação normal de tantos componentes do Windows que, na maioria dos casos, nenhum usuário regular faria isso. para hackers hardcore).

    Com nossa ferramenta de licenciamento , consideramos os seguintes componentes

    • Endereço MAC
    • CPU (não é o número de série, mas o perfil real da CPU, como stepping e modelo)
    • Número de série do inversor do sistema (sem label de volume)
    • Memória
    • Modelo de CD-ROM e fornecedor
    • Modelo de placa de vídeo e fornecedor
    • Controlador IDE
    • Controlador SCSI

    No entanto, em vez de apenas fazer hash nos componentes e criar um sistema de aprovação / reprovação, criamos uma impressão digital comparável que pode ser usada para determinar o quão diferentes são os dois perfis de máquina. Se a diferença estiver acima de uma tolerância especificada, peça ao usuário para ativar novamente.

    Descobrimos que nos últimos oito anos em uso com centenas de milhares de instalações de usuários finais essa combinação funciona bem para fornecer um ID de máquina confiável e exclusivo – até mesmo para máquinas virtuais e instalações de SO clonadas.

    Eu odeio ser o cara que diz “você está fazendo errado” (eu sempre odeio esse cara), mas …

    Tem que ser repetidamente gerado para a máquina única? Você poderia simplesmente atribuir o identificador ou fazer uma chave pública / privada? Talvez se você pudesse gerar e armazenar o valor, você poderia acessá-lo a partir de ambas as instalações do sistema operacional no mesmo disco?

    Você provavelmente já explorou essas opções e elas não funcionam para você, mas se não, é algo a considerar.

    Se não é uma questão de confiança do usuário, você pode usar apenas endereços MAC.

    Que tal apenas usando o UniqueID do processador?

    Você deve procurar usar o endereço MAC na placa de rede (se existir). Esses são geralmente únicos, mas podem ser fabricados. Eu usei software que gera seu arquivo de licença com base no endereço MAC do seu adaptador de rede, por isso é considerado uma maneira bastante confiável de distinguir entre computadores.

    Para um dos meus aplicativos, eu uso o nome do computador se não for um computador de domínio ou o SID da conta de computador do domínio para computadores de domínio. Mark Russinovich fala sobre isso neste post do blog, Machine SID :

    O último caso em que a duplicação de SID seria um problema é se um aplicativo distribuído usasse SIDs de máquina para identificar computadores de maneira exclusiva. Nenhum software da Microsoft faz isso e usar o SID da máquina dessa maneira não funciona apenas pelo fato de que todos os DCs têm o mesmo SID da máquina. O software que depende de identidades de computador exclusivas usa nomes de computador ou SIDs de Domínio de computador (o SID das contas de computador no Domínio).

    Você pode acessar o SID da conta de máquina de domínio via LDAP ou System.DirectoryServices .

    No meu programa eu primeiro verifico o Terminal Server e uso o WTSClientHardwareId. Além disso, o endereço MAC do PC local deve ser adequado.

    Se você realmente quiser usar a lista de propriedades que você forneceu, deixe de lado coisas como Name e DriverVersion , Clockspeed , etc., já que é possivelmente dependente do sistema operacional. Tente produzir as mesmas informações nos dois sistemas operacionais e deixe de lado o que diferir.

    Por que não usar o endereço MAC da sua placa de rede?

    Talvez trapacear um pouco, mas o endereço MAC de um adaptador Ethernet de uma máquina raramente muda sem que a placa-mãe mude nos dias de hoje.

    Você pode pegar algum tipo de número de série do fabricante ou etiqueta de serviço?

    Nossa loja é uma loja da Dell, portanto, usamos a etiqueta de serviço exclusiva de cada máquina para identificá-las. Eu sei que pode ser consultado a partir do BIOS, pelo menos no Linux, mas eu não sei de improviso como fazê-lo no Windows.

    Há uma biblioteca disponível para obter informações específicas de hardware: Extrator de número de série de hardware (CPU, RAM, HDD, BIOS)

    Eu tinha uma restrição adicional, eu estava usando .net express, então eu não poderia usar o mecanismo padrão de consulta de hardware. Então eu decidi usar o power shell para fazer a consulta. O código completo é assim:

     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 

    Procure CPUID para uma opção. Pode haver alguns problemas com sistemas multi-CPU.

    Tente este, ele fornece um ID de disco rígido exclusivo: Port of DiskId32 for Delphi 7-2010 .