web-dev-qa-db-ja.com

一意のマシンIDを生成する

Windows OSを実行している特定のマシンに固有のIDを生成する関数を作成する必要があります。

現在、WMIを使用してさまざまなハードウェアパラメーターを照会し、それらを連結してハッシュ化して一意のIDを導出しています。私の質問は、私が使用すべき推奨パラメータは何ですか?現在、bios\cpu\diskデータの組み合わせを使用して一意のIDを生成しています。また、各メトリックに複数の結果がある場合は、最初の結果を使用しています。

しかし、2つの異なるWindows OSをデュアルブートするマシンが各OSで異なるサイトコードを生成するという問題に遭遇しました。これは理想的には起こりません。

参考までに、これらは私が現在使用している指標です。

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
100
HS.

[〜#〜] smbios [〜#〜] を自分で解析し、任意の長さにハッシュします。使用可能なすべてのSMBIOS構造については、 PDF仕様 を参照してください。

WindowsからSMBIOS情報を照会するには、 EnumSystemFirmwareEntriesEnumSystemFirmwareTables および GetSystemFirmwareTable を使用できます。 =。

IIRC、CPUID命令からの「固有ID」はP3以降では非推奨です。

25
Jonas Gulle

私は同じ問題を抱えていたので、@ Agnusが示唆したように、少し調べてから、レジストリキーHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CryptographyMachineGuidを読むことが最善であると判断しました。 OSのインストール中に生成され、新たにOSを新たにインストールしない限り変更されません。 OSバージョンによっては、埋め込まれたネットワークアダプターMACアドレス(およびランダムを含む他のいくつかの数字)、または新しいOSバージョンの場合は擬似乱数(XP SP2、I信じられますが、確かではありません)理論的には擬似乱数である場合、偽造することができます-リアルタイムクロックを含む2つのマシンの初期状態が同じである場合、実際にはこれはまれですが、ベースとなる場合は注意してください筋金入りのハッカーによって攻撃される可能性があるセキュリティのため。

もちろん、レジストリエントリはだれでも簡単に変更してマシンのGUIDを偽造できますが、これにより、Windowsの多くのコンポーネントの通常の動作が中断され、ほとんどの場合、通常のユーザーは実行できなくなります(もう一度注意してください)筋金入りのハッカー向け)。

72
Fabio Ceconello

ライセンスツール では、次のコンポーネントを考慮します

  • Macアドレス
  • CPU(シリアル番号ではなく、ステッピングやモデルなどの実際のCPUプロファイル)
  • システムドライブのシリアル番号(ボリュームラベルではない)
  • 記憶
  • CD-ROMモデルとベンダー
  • ビデオカードのモデルとベンダー
  • IDEコントローラー
  • SCSIコントローラー

ただし、単にコンポーネントをハッシュして合否システムを作成するのではなく、2つのマシンプロファイルの違いを判断するために使用できる 比較可能なフィンガープリント を作成します。差異評価が指定された許容値を超えている場合は、再度アクティブ化するようユーザーに依頼します。

過去8年間に数十万のエンドユーザーインストールで使用されてきたこの組み合わせは、仮想マシンやクローンOSインストールに対しても信頼性の高い一意のマシンIDを提供するのに適しています。

31
Paul Alexander

プロセッサのUniqueIDを使用するだけではどうですか?

3
gizmo

「あなたは間違っているだけだ」と言う人になるのは嫌いです(私はいつもその人が嫌いです;).

一意のマシンに対して繰り返し生成する必要がありますか?識別子を割り当てるか、公開/秘密キーを実行できますか?値を生成して保存できれば、同じディスク上の両方のOSインストールから値にアクセスできますか?

おそらくこれらのオプションを検討したことがあり、それらはあなたのために機能しませんが、そうでなければ、それは考慮すべきものです。

ユーザーの信頼の問題でない場合は、MACアドレスを使用できます。

2
Sam Hoice

私のプログラムでは、最初にターミナルサーバーをチェックし、WTSClientHardwareIdを使用します。それ以外の場合は、ローカルPCのMACアドレスで十分です。

指定したプロパティのリストを本当に使用したい場合は、NameDriverVersionClockspeedなどを除外します。これは、OSに依存する可能性があるためです。両方のオペレーティングシステムで同じ情報を出力してみて、違いがあるものは除外してください。

1
AngelBlaZe

ネットワークカードのMACアドレスの使用を検討する必要があります(存在する場合)。それらは通常ユニークですが、製作することができます。ネットワークアダプターのMACアドレスに基づいてライセンスファイルを生成するソフトウェアを使用したため、コンピューターを区別するためのかなり信頼できる方法と考えられています。

1
Kyle Cronin

ハードウェア固有の情報を取得するために利用可能なライブラリがあります: ハードウェアシリアル番号抽出(CPU、RAM、HDD、BIOS)

1
ariwez

私のアプリケーションの1つでは、非ドメインコンピューターの場合はコンピューター名を使用するか、ドメインコンピューターのドメインマシンアカウントSIDを使用します。 Mark Russinovichがこのブログ投稿でそれについて語っています Machine SID

SIDの重複が問題となる最後のケースは、分散アプリケーションがコンピューターを一意に識別するためにマシンSIDを使用した場合です。マイクロソフトのソフトウェアはこれを行わず、そのようにマシンSIDを使用しても、すべてのDCが同じマシンSIDを持っているという事実だけでは機能しません。一意のコンピューターIDに依存するソフトウェアは、コンピューター名またはコンピュータードメインSID(ドメイン内のコンピューターアカウントのSID)を使用します。

LDAPまたはSystem.DirectoryServicesを介してドメインマシンアカウントのSIDにアクセスできます。

1
cmcginty

ネットワークカードのMACアドレスを使用してみませんか?

0
Brian Matthews

少しはごまかしているかもしれませんが、最近ではマザーボードが変更されない限り、マシンのイーサネットアダプターのMACアドレスはほとんど変更されません。

0
bfabry

何らかのメーカーのシリアル番号またはサービスタグを引くことはできますか?

私たちの店はデルの店なので、各マシンに固有のサービスタグを使用してそれらを識別します。少なくともLinuxではBIOSからクエリできることは知っていますが、Windowsでそれを行う方法を知らないのです。

0

追加の制約があり、.netエクスプレスを使用していたため、標準のハードウェアクエリメカニズムを使用できませんでした。そこで、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
0
user2515235