Mat*_*son 5 c# powershell x509certificate2 x509
我正在尝试使用 X509 证书,该证书最初是使用 MMC 的“证书”管理单元导入 Windows 10 计算机上的 CurrentUser 密钥库的。在 Windows 8.1 计算机上测试了相同的过程,结果相同。
使用标准的 PowerShell PKI 模块,我使用 Get-Item 获取 X509Certificate2 对象:
$my_cert = Get-Item Cert:\CurrentUser\My\ADAA82188A17THUMBPRINTXXXXXXXXXXX
Run Code Online (Sandbox Code Playgroud)
的输出$my_cert | fl *如下:
PSPath : Microsoft.PowerShell.Security\Certificate::CurrentUser\My\XXXXXXXXXXXXXXXXXXX
PSParentPath : Microsoft.PowerShell.Security\Certificate::CurrentUser\My
PSChildName : XXXXXXXXXXXXXXXXXXX
PSDrive : Cert
PSProvider : Microsoft.PowerShell.Security\Certificate
PSIsContainer : False
EnhancedKeyUsageList : {Secure Email (1.3.6.1.5.5.7.3.4), IP security user (1.3.6.1.5.5.7.3.7), Encrypting File
System (1.3.6.1.4.1.311.10.3.4), Document Signing (1.3.6.1.4.1.311.10.3.12)...}
DnsNameList : {My Name}
SendAsTrustedIssuer : False
EnrollmentPolicyEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
EnrollmentServerEndPoint : Microsoft.CertificateServices.Commands.EnrollmentEndPointProperty
PolicyId : {D52C406F-C279-4BF2-B7C2-EE704290DB3E}
Archived : False
Extensions : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid,
System.Security.Cryptography.Oid, System.Security.Cryptography.Oid...}
FriendlyName :
IssuerName : System.Security.Cryptography.X509Certificates.X500DistinguishedName
NotAfter : 4/15/2017 2:15:16 PM
NotBefore : 4/15/2016 2:15:16 PM
HasPrivateKey : True
PrivateKey :
PublicKey : System.Security.Cryptography.X509Certificates.PublicKey
RawData : {56, 130, 19, 252...}
SerialNumber : 4F0000002F700000000000000000000000
SubjectName : System.Security.Cryptography.X509Certificates.X500DistinguishedName
SignatureAlgorithm : System.Security.Cryptography.Oid
Thumbprint : XXXXXXXXXXXXXXXXXXX
Version : 3
Handle : 2241663016272
Issuer : CN=Issuing CA, DC=My, DC=Domain, DC=us
Subject : E=my.name@my.domain.us, CN=My Name
Run Code Online (Sandbox Code Playgroud)
所以 HasPrivateKey == True,但 PrivateKey == null。我一直在试图弄清楚如何访问私钥以执行加密和解密。我在网上看到的例子似乎都表明 X509Certificate2 类的 PrivateKey 属性应该随时可用,但显然我错过了一些东西。
我在这里读过类似的问题,例如x509certificate2 中的 Empty PrivateKey,但似乎没有一个能解决我的问题。我还阅读了 Paul Stovell 撰写的在 .NET 中使用 X.509 证书的八个技巧,这很有启发性,但最终没有帮助。它确实帮助我验证了私钥是否存在于正确的位置,并且据我所知,具有由 x509Certificate2 类引用的正确权限:
C:\Users\My.Name\AppData\Roaming\Microsoft\SystemCertificates\My\Keys
Run Code Online (Sandbox Code Playgroud)
密钥文件的名称与证书上的主题密钥标识符相匹配。
编辑:
的输出certutil -user -store my "Serial Number"是:
Serial Number: 4f000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Issuer: CN=Issuing CA, DC=My, DC=Domain, DC=us
NotBefore: 4/15/2016 2:15 PM
NotAfter: 4/15/2017 2:15 PM
Subject: E=my.name@my.domain.us, CN=My Name
Non-root Certificate
Template: Userv1, User v1
Cert Hash(sha1): ad ab 82 18 8a 17 4d 75 11 04 48 7c 43 43 d4 05 b9 74 c8 4c
Key Container = te-Userv1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Unique container name: fcbba1aa0xxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Provider = Microsoft Software Key Storage Provider
Encryption test passed
CertUtil: -store command completed successfully.
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么“关键”信息?为什么不能方便地从 X509Certificate2 对象引用私钥?我如何访问它?
您的 certutil 信息显示Provider = Microsoft Software Key Storage Provider这意味着私钥存储在 Windows CNG 下,而不是 Windows CryptoAPI (CAPI) 下。
.NET 4.6 添加了 GetRSAPrivateKey(扩展)方法,以促进让 PrivateKey 属性返回非 RSACryptoServiceProvider(或 DSACryptoServiceProvider)的其他内容的重大更改。如果您有权访问该方法(我不确定 PowerShell 使用哪个版本的框架),那么它将解决您的问题。
不过,有两件事需要注意:
这可能表示以下情况之一:
1) 私钥存储在密钥存储提供程序(而不是传统的加密服务提供程序)中,.NET 对它的支持很差,并且类的PrivateKey属性根本不支持X509Certificate2。您可以通过运行以下命令来检查这一点:
certutil -user -store my "<CertSerialNumber>"
Run Code Online (Sandbox Code Playgroud)
2)私钥丢失。
HasPrivateKey属性不一定反映实际情况,可能True适用于不存在的键或False现有的键。运行上面的 certutil 命令以确保是否提供了密钥。
如果提供了私钥,但绑定已损坏,您可以尝试通过运行以下命令来恢复绑定:
certutil -user -repairstore my "<CertSerialNumber>"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5690 次 |
| 最近记录: |