Ryan Ries lieferte nur eine Teillösung, da dies bei CNG-Schlüsseln nicht funktioniert. Der folgende Code ruft den Containernamen (daher auch den Dateinamen) für CNG-Schlüssel ab:
$signature = @"
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CertGetCertificateContextProperty(
IntPtr pCertContext,
uint dwPropId,
IntPtr pvData,
ref uint pcbData
);
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct CRYPT_KEY_PROV_INFO {
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszContainerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszProvName;
public uint dwProvType;
public uint dwFlags;
public uint cProvParam;
public IntPtr rgProvParam;
public uint dwKeySpec;
}
[DllImport("ncrypt.dll", SetLastError = true)]
public static extern int NCryptOpenStorageProvider(
ref IntPtr phProvider,
[MarshalAs(UnmanagedType.LPWStr)]
string pszProviderName,
uint dwFlags
);
[DllImport("ncrypt.dll", SetLastError = true)]
public static extern int NCryptOpenKey(
IntPtr hProvider,
ref IntPtr phKey,
[MarshalAs(UnmanagedType.LPWStr)]
string pszKeyName,
uint dwLegacyKeySpec,
uint dwFlags
);
[DllImport("ncrypt.dll", SetLastError = true)]
public static extern int NCryptGetProperty(
IntPtr hObject,
[MarshalAs(UnmanagedType.LPWStr)]
string pszProperty,
byte[] pbOutput,
int cbOutput,
ref int pcbResult,
int dwFlags
);
[DllImport("ncrypt.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int NCryptFreeObject(
IntPtr hObject
);
"@
Add-Type -MemberDefinition $signature -Namespace PKI -Name Tools
$CERT_KEY_PROV_INFO_PROP_ID = 0x2 # from Wincrypt.h header file
$cert = dir cert:\currentuser\my\C541C66F490413302C845A440AFA24E98A231C3C
$pcbData = 0
[void][PKI.Tools]::CertGetCertificateContextProperty($cert.Handle,$CERT_KEY_PROV_INFO_PROP_ID,[IntPtr]::Zero,[ref]$pcbData)
$pvData = [Runtime.InteropServices.Marshal]::AllocHGlobal($pcbData)
[PKI.Tools]::CertGetCertificateContextProperty($cert.Handle,$CERT_KEY_PROV_INFO_PROP_ID,$pvData,[ref]$pcbData)
$keyProv = [Runtime.InteropServices.Marshal]::PtrToStructure($pvData,[type][PKI.Tools+CRYPT_KEY_PROV_INFO])
[Runtime.InteropServices.Marshal]::FreeHGlobal($pvData)
$phProvider = [IntPtr]::Zero
[void][PKI.Tools]::NCryptOpenStorageProvider([ref]$phProvider,$keyProv.pwszProvName,0)
$phKey = [IntPtr]::Zero
[void][PKI.Tools]::NCryptOpenKey($phProvider,[ref]$phKey,$keyProv.pwszContainerName,0,0)
$pcbResult = 0
[void][PKI.Tools]::NCryptGetProperty($phKey,"Unique Name",$null,0,[ref]$pcbResult,0)
$pbOutput = New-Object byte[] -ArgumentList $pcbResult
[void][PKI.Tools]::NCryptGetProperty($phKey,"Unique Name",$pbOutput,$pbOutput.length,[ref]$pcbResult,0)
[Text.Encoding]::Unicode.GetString($pbOutput)
[void][PKI.Tools]::NCryptFreeObject($phProvider)
[void][PKI.Tools]::NCryptFreeObject($phKey)
Ich habe den Code von CryptoGuy verwendet, ihn erheblich erweitert und in eine Funktion umgewandelt. Es gibt jedoch noch Raum für Verbesserungen. Danke, CryptoGuy!
quelle