Générer un identifiant de machine unique


104

J'ai besoin d'écrire une fonction qui génère un identifiant unique pour une machine donnée exécutant un système d'exploitation Windows.

Actuellement, j'utilise WMI pour interroger divers paramètres matériels, les concaténer et les hacher pour obtenir l'identifiant unique. Ma question est la suivante: quels sont les paramètres suggérés que je devrais utiliser? Actuellement, j'utilise une combinaison de données bios \ cpu \ disk pour générer l'identifiant unique. Et j'utilise le premier résultat si plusieurs résultats sont là pour chaque métrique.

Cependant, j'ai rencontré un problème où une machine qui démarre deux fois dans 2 systèmes d'exploitation Windows différents génère des codes de site différents sur chaque système d'exploitation, ce qui ne devrait idéalement pas se produire.

Pour référence, voici les métriques que j'utilise actuellement:

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

Réponses:


25

Analysez le SMBIOS vous-même et hachez-le à une longueur arbitraire. Voir la spécification PDF pour toutes les structures SMBIOS disponibles.

Pour interroger les informations SMBIOS de Windows, vous pouvez utiliser EnumSystemFirmwareEntries, EnumSystemFirmwareTableset GetSystemFirmwareTable.

IIRC, «l'identifiant unique» de l'instruction CPUID est obsolète à partir de P3 et plus récent.


14
Notez que ces fonctions nécessitent au moins Windows Vista, Windows XP Professionnel Édition x64, Windows Server 2008 ou Windows Server 2003 avec SP1.
jcoffland

33
Une note pour ne pas faire ce que j'ai fait, qui était d'appeler GetSystemFirmwareTable ('RSMB' ...); et hachez tout le tampon SMBIOSTableData. Cela fonctionnait très bien jusqu'à ce que je tombe sur un poste de travail qui écrit sa température interne du processeur sur cette table, ce qui signifie que mon identifiant unique change toutes les quelques secondes.
Thomas

Existe-t-il un code source disponible pour cette solution?
Just Shadow

@Thomas alors quelle solution avez-vous finalement choisie?
Smith

@Smith Mon objectif était un petit identifiant de 8 caractères. En lisant les spécifications, j'ai pris des décisions sur les champs susceptibles de varier et les ai exclus. Ensuite, pendant de nombreuses années, j'ai supprimé plus de champs qui ne sont pas des constantes de machines. Enfin, j'ai fini par stocker une copie cryptée des données brutes que j'ai utilisées comme entrée et j'ai créé une closeEnoughfonction pour que j'accepte un identifiant non correspondant s'il ne variait que dans 2 champs. J'inclus également des détails sur le processeur et le disque dur du système dans mon hachage car au début, j'ai eu des collisions entre des systèmes identiques.
Thomas

72

J'ai eu le même problème et après quelques recherches, j'ai décidé que le mieux serait de lire MachineGuiddans la clé de registre HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, comme @Agnus l'a suggéré. Il est généré lors de l'installation du système d'exploitation et ne changera pas à moins que vous ne fassiez une autre installation du système d'exploitation. Selon la version du système d'exploitation, il peut contenir l'adresse MAC de la carte réseau intégrée (plus d'autres nombres, y compris aléatoires), ou un numéro pseudo-aléatoire, le plus tard pour les versions de système d'exploitation plus récentes (après XP SP2, je crois, mais pas sûr). S'il s'agit d'un pseudo-aléatoire théoriquement, il peut être forgé - si deux machines ont le même état initial, y compris l'horloge en temps réel. En pratique, ce sera rare, mais sachez si vous vous attendez à ce que ce soit une base de sécurité pouvant être attaquée par des hackers hardcore.

Bien sûr, une entrée de registre peut également être facilement modifiée par n'importe qui pour forger un GUID machine, mais ce que j'ai trouvé, c'est que cela perturberait le fonctionnement normal de tant de composants de Windows que dans la plupart des cas aucun utilisateur régulier ne le ferait (encore une fois, faites attention pour les hackers hardcore).


6
Vous pouvez utiliser l'indicateur KEY_WOW64_64KEY pour vous assurer que vous obtenez toujours la version "réelle" de la clé de registre, je pense.
Colen

13
Si vous clonez une image de lecteur, cela restera le même. Ce n'est donc pas du tout inviolable et très peu sûr.
bitbonk

19
Pour clarifier ce point, lorsque je mets des mesures DRM dans un logiciel, mon objectif principal est d'empêcher les gens de créer une fissure qui permet aux pirates «professionnels» de vendre des copies illégales du logiciel sans aucune limitation. Je ne suis pas si inquiet d'un pirate informatique occasionnel qui clone le lecteur de son ami juste pour pouvoir utiliser mon logiciel. Dans de tels cas, ces personnes ont généralement plus de temps que d'argent et ne paieraient pas pour cela de toute façon. Si le logiciel coûte 100 $ et que votre salaire est supérieur à 50 $ / h, il vous suffit de le payer. Les tracas prendront plus de votre temps que 2h.
Fabio Ceconello

7
En particulier, dans un environnement où Windows est installé par clonage d'une image de machine maître, le MachineGuid sera identique pour tous.
nandhp

8
Pas si vous faites cela correctement et légalement, en utilisant sysprep & all. Pour ceux qui ont piraté des copies de Windows et "juste cloner", c'est une autre affaire. Mais ils ne seraient pas arrêtés aussi facilement, de toute façon.
Fabio Ceconello

34

Avec notre outil de licence, nous considérons les composants suivants

  • Adresse Mac
  • CPU (pas le numéro de série, mais le profil du processeur réel comme le pas à pas et le modèle)
  • Numéro de série du lecteur système (pas d'étiquette de volume)
  • Mémoire
  • Modèle et fournisseur de CD-ROM
  • Modèle et fournisseur de carte vidéo
  • Contrôleur IDE
  • Contrôleur SCSI

Cependant, plutôt que de simplement hacher les composants et de créer un système réussite / échec, nous créons une empreinte digitale comparable qui peut être utilisée pour déterminer à quel point deux profils de machine sont différents. Si le taux de différence est supérieur à une tolérance spécifiée, demandez à l'utilisateur de l'activer à nouveau.

Nous avons constaté au cours des 8 dernières années, en cours d'utilisation avec des centaines de milliers d'installations d'utilisateurs finaux, que cette combinaison fonctionne bien pour fournir un identifiant de machine unique et fiable, même pour les machines virtuelles et les installations de système d'exploitation clonées.


1
Comment déterminez-vous quelle adresse MAC vous utilisez? Une machine peut avoir plusieurs cartes réseau et celles-ci sont ajoutées dynamiquement (la connexion à un nouveau VPN via une applet ajoutera une carte réseau virtuelle). Certains sont virtuels, sont de type Ethernet et sont difficiles à identifier comme virtuels. D'autres sont haut / bas en fonction des conditions du réseau (wifi)
Marek

Nous utilisons tous les NIC physiques - à l'exception des NICS virtuels, blue-tooth, etc. Ils sont tous combinés pour créer un hachage unifié.
Paul Alexander

Pourquoi recommandez-vous de ne pas utiliser le numéro de série du processeur?
Mojtaba Rezaeian

3
Le numéro de série du processeur n'a pas été activé dans une puce Intel depuis des années. Les appels système existent toujours, mais ils ne renvoient pas de valeur stable. Je ne me souviens plus de ce qu'il renvoie - soit des données factices, soit la même valeur pour toutes les machines. de toute façon, ce n'est pas une métrique matérielle fiable.
Paul Alexander

1
@PaulAlexander l'outil auquel vous avez fait référence valide tous les paramètres que vous avez mentionnés ou peu d'entre eux fonctionneront? Parce que les systèmes de nos jours ne consistent généralement pas en un CD-ROM
FaizanHussainRabbani

3

Qu'en est-il simplement de l'utilisation de l'identifiant unique du processeur?


14
N'est-ce pas une propriété dépréciée de nos jours?
Jake Wilson

15
Peut-être qu'il veut dire `` obsolète '' ... Les fabricants de processeurs ont commencé à insérer des identifiants uniques à un moment donné, mais en raison de réactions négatives sur les questions de confidentialité, ils ont de nouveau arrêté. Ainsi, vous constaterez que certains ont un identifiant unique, mais pas la plupart des processeurs modernes.
TripleAntigen

1
Pour référence, seul un bref lot de Pentium III avait des numéros de série de processeurs lisibles. Alors que les versions ultérieures avaient un numéro de série, il était désactivé par défaut. Les processeurs Pentium IV et ultérieurs ne le supportaient tout simplement pas.
Paul Alexander

2

Je déteste être le gars qui dit, "tu fais juste mal" (je déteste toujours ce gars;) mais ...

Doit-il être généré de manière répétée pour la machine unique? Pourriez-vous simplement attribuer l'identifiant ou créer une clé publique / privée? Peut-être que si vous pouviez générer et stocker la valeur, vous pourriez y accéder à partir des deux installations du système d'exploitation sur le même disque?

Vous avez probablement exploré ces options et elles ne fonctionnent pas pour vous, mais sinon, c'est quelque chose à considérer.

Si ce n'est pas une question de confiance des utilisateurs, vous pouvez simplement utiliser des adresses MAC.


5
Les adresses MAC ne fonctionneront pas si la machine ne possède pas de carte réseau.
Brian

7
@Brian - avez-vous vraiment besoin d'une valeur unique pour identifier un ordinateur qui n'a pas de carte réseau? Semble une valeur sûre que la machine a une carte.
romandas

1

Vous devriez examiner l'utilisation de l'adresse MAC sur la carte réseau (si elle existe). Ceux-ci sont généralement uniques mais peuvent être fabriqués. J'ai utilisé un logiciel qui génère son fichier de licence en fonction de l'adresse MAC de votre carte réseau, il est donc considéré comme un moyen assez fiable de distinguer les ordinateurs.


6
Non, ils ne le sont pas. De nombreux fabricants vous permettent de les changer. Ceci est très utile lorsque vous travaillez avec des clusters, car certains fournisseurs vous donnent tous les ordinateurs avec la même adresse MAC (nous avons rencontré ce problème il y a quelques années).
gizmo

C'est une idée valide dans de nombreux cas, la question ne spécifie pas le spoof-proodness ou hors ligne - vous voulez généralement générer un identifiant unique si vous voulez vous identifier dans un réseau
Hurda

Il est possible d'avoir plusieurs périphériques réseau dans la même machine; vous n'êtes pas assuré qu'ils seront toujours détectés dans le même ordre ou qu'ils ne seront pas remplacés à un moment donné. Il est préférable d'utiliser du matériel susceptible d'être plus permanent.
Agi Hammerthief

1

Pour l'une de mes applications, j'utilise soit le nom de l'ordinateur s'il ne s'agit pas d'un ordinateur de domaine, soit le SID du compte d'ordinateur de domaine pour les ordinateurs de domaine. Mark Russinovich en parle dans ce billet de blog, Machine SID :

Le dernier cas où la duplication de SID serait un problème est si une application distribuée utilisait les SID de machine pour identifier de manière unique les ordinateurs. Aucun logiciel Microsoft ne le fait et utiliser le SID de la machine de cette manière ne fonctionne pas uniquement parce que tous les DC ont le même SID de la machine. Les logiciels qui reposent sur des identités d’ordinateur uniques utilisent des noms d’ordinateur ou des SID de domaine d’ordinateur (le SID des comptes d’ordinateur dans le domaine).

Vous pouvez accéder au SID du compte d'ordinateur du domaine via LDAP ou System.DirectoryServices.


1

Dans mon programme, je vérifie d'abord Terminal Server et j'utilise WTSClientHardwareId. Sinon, l'adresse MAC du PC local devrait être adéquate.

Si vous voulez vraiment utiliser la liste des propriétés que vous avez fourni un congé des choses comme Nameet DriverVersion, Clockspeed, etc. , car il est peut - être OS dépendant. Essayez de sortir les mêmes informations sur les deux systèmes d'exploitation et laissez de côté celles qui diffèrent entre elles.



0

Pourquoi ne pas utiliser l'adresse MAC de votre carte réseau?


14
L'adresse Mac peut être usurpée
Henry B

C'est une idée valide dans de nombreux cas, la question ne spécifie pas le spoof-proodness ou hors ligne - vous voulez généralement générer un identifiant unique si vous voulez vous identifier dans un réseau
Hurda

0

Peut-être tricher un peu, mais l'adresse MAC d'un adaptateur Ethernet d'une machine change rarement sans que la carte mère ne change ces jours-ci.


De nombreux fabricants vous permettent de les changer. Ceci est très utile lorsque vous travaillez avec des clusters, car certains fournisseurs vous donnent tous les ordinateurs avec la même adresse MAC (nous avons rencontré ce problème il y a quelques années).
gizmo

1
MAC est totalement peu fiable car il peut être si facilement modifié (juste pour une recherche Google et vous verrez de nombreux outils gratuits qui font cela). La même chose pour WMI.
InTheNameOfScience

0

Pouvez-vous extraire une sorte de numéro de série du fabricant ou une étiquette de service?

Notre boutique est une boutique Dell, nous utilisons donc l'étiquette de service qui est unique à chaque machine pour les identifier. Je sais que cela peut être interrogé à partir du BIOS, au moins sous Linux, mais je ne sais pas comment le faire sous Windows.


0

J'avais une contrainte supplémentaire, j'utilisais .net express donc je ne pouvais pas utiliser le mécanisme de requête matériel standard. J'ai donc décidé d'utiliser Power Shell pour faire la requête. Le code complet ressemble à ceci:

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

-1

Recherchez CPUID pour une option. Il peut y avoir des problèmes avec les systèmes multi-processeurs.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.