gpt4 book ai didi

powershell - 使用 UniqueKeyContainerName 获取证书绝对路径

转载 作者:行者123 更新时间:2023-12-02 11:24:24 25 4
gpt4 key购买 nike

给定证书指纹,我想在本地文件系统上找到证书的绝对文件路径。

这个片段几乎总是有效。

$thumb    = <mythumbprint string>

$cert = Get-ChildItem "Cert:\LocalMachine\My" | Where-Object {$_.Thumbprint -eq $thumb};
$keyName = (($cert.PrivateKey).CspKeyContainerInfo).UniqueKeyContainerName
$keyPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\"
$fullPath = $keyPath+$keyName

它在私钥不可导出的证书上失败。当标记为不可导出时,$cert.PrivateKey 不再可访问,因此无法构建证书的完整路径。

是否有 Powershell 替代方案来确定证书的 UniqueKeyContainerName?

更新:我关心的所有证书都有私钥。问题是我不能假设它们被标记为可导出。如果未标记为可导出,则无法引用 .PrivateKey。我需要另一种方法来获取 UniqueKeyContainerName 而不通过 .Privatekey 链接

最佳答案

关于此主题的有用信息似乎很少,更不用说 PowerShell 5.1 和 7.1 (.NET Core) 了。希望这个helps某人。

我改编自 Vadims Podāns 'Retrieve CNG key container name and unique name'

请注意:

  • Cmdlet 的使用示例:Get-Item 'Cert:\LocalMachine\My\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' |获取证书容器绝对路径
  • 我作弊,只是在 Microsoft Crypto 目录层次结构下递归搜索 key 文件,而不是搜索正确的特定子目录
  • 尽管使用了 CNG Provider,但这似乎不利于我创建的测试 CryptoAPI 提供的 key
  • 我在 Windows 上的 Powershell 5.1 和 7.1 上对此进行了测试。
if(-not ('EmbeddedTemporary.PKITools' -as [type])) {
$PKIToolsDefinition = @"
[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 $PKIToolsDefinition -Namespace 'EmbeddedTemporary' -Name 'PKITools'
}

Function Get-CertificateContainerAbsolutePath {
[CmdletBinding()]
Param(
[Parameter(Mandatory,ValuefromPipeline)]
$Certificate
)
$CERT_KEY_PROV_INFO_PROP_ID = 0x2 # from Wincrypt.h header file
$pcbData = 0
[EmbeddedTemporary.PKITools]::CertGetCertificateContextProperty($Certificate.Handle, $CERT_KEY_PROV_INFO_PROP_ID, [IntPtr]::Zero, [ref]$pcbData) | Out-Null
$pvData = [Runtime.InteropServices.Marshal]::AllocHGlobal($pcbData)
[EmbeddedTemporary.PKITools]::CertGetCertificateContextProperty($Certificate.Handle, $CERT_KEY_PROV_INFO_PROP_ID, $pvData, [ref]$pcbData) | Out-Null
$keyProv = [Runtime.InteropServices.Marshal]::PtrToStructure($pvData, [type][EmbeddedTemporary.PKITools+CRYPT_KEY_PROV_INFO])
[Runtime.InteropServices.Marshal]::FreeHGlobal($pvData) | Out-Null

$CngProvider = [System.Security.Cryptography.CngProvider]::new($keyProv.pwszProvName)
$CngKey = [System.Security.Cryptography.CngKey]::Open($keyProv.pwszContainerName, $CngProvider, [System.Security.Cryptography.CngKeyOpenOptions]::MachineKey)
$UniqueName = $CngKey.UniqueName
$CngKey.Dispose()

$Certificates = Get-ChildItem -Path (Join-Path -Path $Env:ProgramData -ChildPath 'Microsoft\Crypto') -Recurse -Filter $UniqueName
$Certificates.FullName
}

关于powershell - 使用 UniqueKeyContainerName 获取证书绝对路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20361395/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com