可以在 PowerShell 中查看 msDS-KeyCredentialLink 属性。 但是,该值采用二进制格式,无法读取。 此脚本可帮助你执行以下作:
- 枚举在 msDS-KeyCredentialLink** 中**具有非 null 值的 Active Directory(AD)中的所有用户。
- 提取 msDS-KeyCredentialLink** 中**保存的每个证书的 bcrypt-sha256 密钥 ID 哈希,并将其保存到文件中。
然后,可以使用保存的信息来检查预期值是否位于用户的 msDS-KeyCredentialLink 属性中。
Script
重要
此示例脚本在任何Microsoft标准支持计划或服务下都不受支持。
示例脚本按原样提供,没有任何保证。 Microsoft进一步否认所有默示担保,包括不限于适销性或针对特定用途的适用性的任何默示担保。
示例脚本和文档的使用或性能导致的整个风险依然存在。 在任何情况下,不得Microsoft、其作者或参与创建、制作或交付脚本的任何其他人对任何损害负责(包括但不限于业务利润损失、业务中断、业务中断、业务信息损失或其他经济损失)因使用或无法使用示例脚本或文档而导致的损害。 即使Microsoft被告知这种损害的可能性。
运行脚本后,结果将保存在文件 C:\temp\KeyCredentialLink-report.txt中。
$outputfile = "C:\temp\KeyCredentialLink-report.txt"
New-Item -ItemType file -Path $outputfile -Force | Out-Null
"Report generated on " + (Get-Date) | Out-File $outputfile
# Enumerate all AD users that has a msds-KeyCredentialLink value
foreach ($user in (Get-ADUser -LDAPFilter '(msDS-KeyCredentialLink=*)' -Properties "msDS-KeyCredentialLink")) {
# For each user, output the UPN, DN, and all key IDs in msDS-KeyCredentialLink
"===========`nUser: $($user.UserPrincipalName)`nDN: $($user.DistinguishedName)" | Out-File $outputfile -Append
"KeyCredialLink Entries:" | Out-File $outputfile -Append
" Source|Usage|DeviceID |KeyID" | Out-File $outputfile -Append
" -------------------------------------------------------------------" | Out-File $outputfile -Append
foreach ($blob in ($user."msDS-KeyCredentialLink")) {
$KCLstring = ($blob -split ':')[2]
# Check that the entries are version 2
if ($KCLstring.Substring(0, 8) -eq "00020000") {
$curIndex = 8
# Parse all KeyCredentialLink entries from the hex string
while ($curIndex -lt $KCLstring.Length) {
# Read the length, reverse the byte order to account for endianess, then convert to an int
# The length is in bytes, so multiply by 2 to get the length in characters
$strLength = ($KCLstring.Substring($curIndex, 4)) -split '(?<=\G..)(?!$)'
[array]::Reverse($strLength)
$kcle_Length = ([convert]::ToInt16(-join $strLength, 16)) * 2
# Read the identifier and value
$kcle_Identifier = $KCLstring.Substring($curIndex + 4, 2)
$kcle_Value = $KCLstring.Substring($curIndex + 6, $kcle_Length)
switch ($kcle_Identifier) {
# KeyID
'01' {
$KeyID = $kcle_Value
}
# KeyUsage
'04' {
switch ($kcle_Value) {
'01' { $Usage = "NGC " }
'07' { $Usage = "FIDO " }
'08' { $Usage = "FEK " }
Default { $Usage = $kcle_Value }
}
}
# Source
'05' {
switch ($kcle_Value) {
'00' { $Source = "AD " }
'01' { $Source = "Entra " }
Default { $Source = $kcle_Value }
}
}
# DeviceID
'06' {
$tempByteArray = $kcle_Value -split '(?<=\G..)(?!$)'
$DeviceID = [System.Guid]::new($tempByteArray[3..0] + $tempByteArray[5..4] + $tempByteArray[7..6] + $tempByteArray[8..16] -join "")
}
}
$curIndex += 6 + $kcle_Length
}
# Save the data to file
" $Source|$Usage|$DeviceID|$KeyID" | Out-File $outputfile -Append
}
}
}
脚本示例输出和分析
下面是脚本的示例输出:
User: user1@contoso.com
DN: CN=user1,OU=MyOU,DC=contoso,DC=com
KeyCredialLink Entries:
Source|Usage|DeviceID |KeyID
-------------------------------------------------------------------
Entra |NGC |8a763ab0-0f6f-44f3-99ae-599a6aaca45b|FD68391824C44158B23C5605F567A588D02C4B2962AC96B789EDBCE091CF5067
Entra |NGC |9cf88f41-1e1e-462b-87d5-6938410ea82c|E91EF4E058513155A3F7E7E5B3E34951ADE923FFD0A7C24BB9957510F007E2F3
Entra |NGC |d04581fc-d1c8-45fc-a5ad-192bc649574f|E60B476088CC5CDF6FB75454CFA6E17C3059D51F2CA1E414E1554715BE6C0527
===========
User: user2@contoso.com
DN: CN=user2,OU=MyOU,DC=contoso,DC=com
KeyCredialLink Entries:
Source|Usage|DeviceID |KeyID
---------------------------
Entra |NGC |c8fcc7a6-8f3f-4ec7-a90b-49c6988ba3a4|32EF67B902CB498710F0091F5B10B6A4A2F05D621B748B8150E08FA3048F227F
每个 KeyCredentialLink 条目表示证书。 输出包含以下信息:
Source:证书的源。 此信息可以来自 Microsoft Entra ID 或本地 AD。Usage:证书的已定义用法。 此信息可以是 NGC (WHfB)、FIDO 或 FEK (文件加密密钥)。DeviceID:创建证书的计算机的 ID。 此信息是 Microsoft Entra ID 中的设备 ID 和 AD 中的 objectGUID。KeyID:证书的 bcrypt-sha256 密钥 ID 哈希。
匹配的证书应位于具有匹配 DeviceID项的计算机上的用户个人证书存储中。 若要查找客户端上使用的证书,可以从 PowerShell 或命令提示符运行 certutil -v -user -store my ,以转储用户个人存储中的详细证书信息。 在此示例中,应找到一个自签名证书,其中使用者和颁发者相同,并且格式相同 CN=<User SID>/login.windows.net/<Tenant ID>/<user UPN>。 找到此证书后,请检查 bcrypt-sha256 密钥 ID 哈希。 此哈希值应与 msDS-KeyCredentialLink** 属性中的**一个条目匹配。
下面是“证书存储”的摘录 user2@contoso.com:
> certutil -v -user -store my
my "Personal"
================ Certificate 0 ================
X509 Certificate:
Version: 3
Serial Number: 184621…
Signature Algorithm:
Algorithm ObjectId: 1.2.840.113549.1.1.11 sha256RSA
Algorithm Parameters:
05 00
Issuer:
CN=S-1-5-21-394…7436/login.windows.net/ccf…83a/user2@contoso.com
:
Signature Algorithm:
Algorithm ObjectId: 1.2.840.113549.1.1.11 sha256RSA
Algorithm Parameters:
05 00
Signature: UnusedBits=0
0000 19 17 8f 65 c1 e3 f1 0a 3b 62 90 7f fa 94 13 ad
// snip
00f0 a2 e3 72 54 a5 0a 84 30 9e 8b 81 19 d3 61 46 58
Signature matches Public Key
Root Certificate: Subject matches Issuer
Key Id Hash(rfc-sha1): 9a546…
Key Id Hash(sha1): d66eb…
Key Id Hash(bcrypt-sha1): 7f4a0…
Key Id Hash(bcrypt-sha256): 32ef67b902cb…