Partager via


Scripts : afficher les informations de certificat dans l’attribut msDS-KeyCredentialLink à partir d’objets utilisateur AD

L’attribut msDS-KeyCredentialLink peut être consulté dans PowerShell. Toutefois, la valeur est au format binaire et ne peut pas être lue. Ce script vous aide à effectuer les opérations suivantes :

  • Énumérez tous les utilisateurs dans Active Directory (AD) qui ont une valeur non null dans msDS-KeyCredentialLink.
  • Extrayez le hachage de l’ID de clé bcrypt-sha256 de chaque certificat enregistré dans msDS-KeyCredentialLink et enregistrez-le dans un fichier.

Vous pouvez ensuite utiliser les informations enregistrées pour vérifier si les valeurs attendues se trouvent dans l’attribut msDS-KeyCredentialLink de l’utilisateur.

Script

Important

Cet exemple de script n’est pas pris en charge dans le cadre d’un programme ou d’un service de support standard Microsoft.

L’exemple de script est fourni AS IS sans garantie quelconque. Microsoft exclut en outre toutes les garanties implicites, y compris, sans limitation, toute garantie implicite de marchandabilité ou d’adéquation à un usage particulier.

Tout le risque résultant de l’utilisation ou des performances des exemples de scripts et de la documentation reste avec vous. En aucun cas, Microsoft, ses auteurs ou toute autre personne impliquée dans la création, la production ou la livraison des scripts ne sont responsables de tout dommage que ce soit (y compris, sans limitation, dommages pour perte de bénéfices commerciaux, interruption d’activité, perte d’informations commerciales ou toute autre perte de fonds) résultant de l’utilisation ou de l’incapacité d’utiliser les exemples de scripts ou de documentation, même si Microsoft a été informé de la possibilité de tels dommages.

Après avoir exécuté le script, les résultats sont enregistrés dans le fichier 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
        }
    }
}

Exemple de sortie et d’analyse de script

Voici un exemple de sortie du script :

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

Chaque KeyCredentialLink entrée représente un certificat. La sortie contient les informations suivantes :

  • Source: source du certificat. Ces informations peuvent provenir de Microsoft Entra ID ou d’AD local.
  • Usage: utilisation définie du certificat. Ces informations peuvent être NGC (WHfB), FIDO ou FEK (clé de chiffrement de fichier).
  • DeviceID: ID de l’ordinateur sur lequel le certificat a été créé. Ces informations sont l’ID d’appareil dans Microsoft Entra ID et l’objectGUID dans AD.
  • KeyID: hachage de l’ID de clé bcrypt-sha256 du certificat.

Le certificat correspondant doit se trouver dans le magasin de certificats personnel de l’utilisateur sur l’ordinateur avec la correspondance DeviceID. Pour trouver le certificat utilisé sur le client, vous pouvez exécuter à certutil -v -user -store my partir d’une invite de commandes Ou PowerShell pour vider des informations détaillées sur le certificat du magasin personnel de l’utilisateur. Dans cet exemple, vous devez trouver un certificat auto-signé où l’objet et l’émetteur sont identiques et sous la forme .CN=<User SID>/login.windows.net/<Tenant ID>/<user UPN> Une fois ce certificat trouvé, vérifiez le hachage de l’ID de clé bcrypt-sha256. Cette valeur de hachage doit correspondre à l’une des entrées de l’attribut msDS-KeyCredentialLink .

Voici un extrait du magasin de user2@contoso.comcertificats :

> 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…

Référence

Structures des liens d’informations d’identification clés