C# 检查CSR的签名(X.509证书签名请求)

C# 检查CSR的签名(X.509证书签名请求),c#,powershell,certificate,x509,pki,C#,Powershell,Certificate,X509,Pki,有人能帮我回答以下问题吗 我想检查CSR X509证书签名请求上的签名是否正确 有效的 我相信我知道如何做到这一点,但不确定我的理解是否正确,如果有人能检查/纠正/确认我的方法,我将不胜感激 我正在使用PowerShell,但也了解C'的基本概念 我的硬盘上有一个文本文件,基本上是一个base64编码的CSR文件,名为CSR.txt 因此,在PowerShell中,我执行以下操作 $CSR=获取内容c:\temp\CSR.txt–原始 $requestcomObject=新对象-ComObjec

有人能帮我回答以下问题吗

我想检查CSR X509证书签名请求上的签名是否正确 有效的 我相信我知道如何做到这一点,但不确定我的理解是否正确,如果有人能检查/纠正/确认我的方法,我将不胜感激

我正在使用PowerShell,但也了解C'的基本概念 我的硬盘上有一个文本文件,基本上是一个base64编码的CSR文件,名为CSR.txt

因此,在PowerShell中,我执行以下操作

$CSR=获取内容c:\temp\CSR.txt–原始 $requestcomObject=新对象-ComObject X509enrollment.CX509CertificateRequestsPKCS10 $RequestComObj.初始化代码$CSR,6

现在我有了CSR,它上面有一个CheckSignature方法,需要构造函数中有一个pkcs10AllowedSignatureType,当我查看这个时,我看到有两个十六进制值代表可能的选项

AllowedKeySignature=0x1 AllowedNullSignature=0x2

根据我目前阅读/尝试的内容,我可以将这两个值中的一个传递给构造函数,例如,0x1代表SHA1,0x2代表SHA2 SHA256 因此,我的问题是,如果我有一个使用SHA1签名的CSR,我想检查这个SHA1签名是否有效,脚本的最后一部分应该是这样的

$RequestComObj.CheckSignature0x1

或者可能只是

$RequestComObj.CheckSignature1

如果CSR签署了SHA2,我将使用

$RequestComObj.CheckSignature0x2

或者可能只是

$RequestComObj.CheckSignature2

当我尝试上述PowerShell时,如果CSR被相应地签名,则不会向控制台返回任何内容,这对于PowerShell来说是正常的,即如果没有错误,则不会返回任何内容

以上是正确的吗?e、 g.我认为这对检查签名有效

谢谢大家

__奥塞尔

我正在编辑我的问题,以回应以下答案,因为答案太大,无法作为评论发布

你好,vcsjones和Crypt32

非常感谢你们两位花时间回答我的问题,COM>CRL包装和错误屏蔽对我更广泛的理解非常有帮助

因此,如果我理解正确,请原谅我,我不是程序员/开发人员,如果我像上面那样使用0x1,它只检查摘要(例如哈希是SHA1和OK),而不检查签名是否是该摘要的正确签名?换句话说,可能有一个有效的签名,但对于不同的摘要,如果使用0x1,它仍然会通过

请问我上面的理解正确吗

如果是这样,这是否也意味着使用上面的0x2将检查摘要是否为SHA2,而不是签名是否实际属于该摘要

也 您在上面提到过,我应该使用密钥签名,而不是使用CheckSignature

当我查看上面$RequestComObj PowerShell对象的成员时,我没有看到名为KeySignature的成员,除非它埋得更深,而我看到的是下面收集的COM成员

Type                        : 1
EnrollmentContext           : 1
Silent                      : False
ParentWindow                :
UIContextMessage            :
SuppressDefaults            : False
ClientId                    : 9
CspInformations             :
HashAlgorithm               : System.__ComObject
AlternateSignatureAlgorithm : False
TemplateObjectId            :
PublicKey                   : System.__ComObject
PrivateKey                  :
NullSigned                  : False
ReuseKey                    : False
Subject                     : System.__ComObject
CspStatuses                 :
SmimeCapabilities           : False
SignatureInformation        : System.__ComObject
KeyContainerNamePrefix      :
CryptAttributes             : System.__ComObject
X509Extensions              : System.__ComObject
CriticalExtensions          : System.__ComObject
SuppressOids                : System.__ComObject
PolicyServer                :
Template                    :
AttestPrivateKey            : False
EncryptionAlgorithm         :
EncryptionStrength          :
ChallengePassword           :
NameValuePairs              : System.__ComObject
ClaimType                   :
AttestPrivateKeyPreferred   : False
根据上面的计算,我可以使用以下方法获得签名和公钥的Base64编码版本

$RequestComObj.Signature()

ysZ//Y3EvJnCy3UoBwhZlIoIh7w733+kocDJ9i3+jMdpFu/2YEF6jQQ3UZ8vbrdC
eq6ORbL9yZX2LlBM/H5w30in/ipM9KR3Ynv1ssc0eLyCNL5HILxdgREAFqpTDM6F
3XFpRtzffHs0C5czrIgDmncncKLsUeRVtd4Z9QfP7NnFoiUaquKLFou0ANn7X5cK
LLe9nzYsi9/fuAj6gQAgBTKWWY17ke8nFlPtQsQlxP3nIPLEpDVDZCcvTRcgaamA
xwKsf4isW1zjHkv6pvMEtjuxkrX0/Y91VuPx2WnbciFmpYIH9cE1oKG3L3J34w6d
mcHwPy0EmPZ8bJjL9hiBMA==


$RequestComObj.PublicKey.EncodedKey()

MIIBCgKCAQEAlQdqVHQgzd1uJ9MFb935Vfyg1Y1mZXn4OMwJudOhEzx7m1+4C8lD
OXn5hglHG0FFad+KkLok/GcAzdc2iwBOholJ2MYPXCnfkJLYXHLRj+CKRvhCHWJO
XkQQQ0apdXh1MhiDBD/BIKqmMm54XLFhZqjQiNeIVHFb9GS06Ps/xuOWzqY54xSM
/047nzYNU50FrTHuBCiqtJtHpKtdrCWyhWi7was0noCx/XGm6g8nVnzPTQCSeAPp
6mSt4kSMtdoVZYg1n5pmMW+QYAero/UWrbNp1WlkpUH4s96H6pUrbF7RIkXpCwWo
cxBHAXVcMst2HYvwstAETxvqeKTOvVEEAQIDAQAB
所以现在我想我有CSR,我有签名,我有来自这三条信息的公钥,我必须能够检查CSR上的签名是否有效

我只是需要一些代码的帮助,如果你愿意的话,请找C,因为我可以在PowerShell中使用它

再次非常感谢,非常感谢

__奥塞尔

根据我迄今为止阅读和尝试的内容,我可以向构造函数传递这两个值中的一个:例如,0x1表示SHA1,0x2表示SHA2 SHA256

这并不完全正确。CheckSignature接受一个参数,该参数指示允许哪种类型的签名,必要时可以按位组合

如果使用了NullSignature,则根本不验证签名,验证的只是CSR摘要。如果使用密钥签名,则CSR的签名将根据用于验证CSR的公钥进行验证


除非您明确需要不验证非对称签名,否则您应该始终将0x01传递给CheckSignature。

最后一段对于.NET和PowerShell来说是完全不正确的。只是解释一下:CertEnroll是一组COM接口。CLR PS、.NET无法直接与COM world通信,COM world无法直接与CLR通信。他们使用代理:COM可调用包装CCW来通信:COM->CLR,运行时可调用包装RCW来通信CLR->COM。RCW通过将返回类型更改为void和非零HRESULT转换为托管异常来抑制S_OK代码。因此,OP的解释是完全正确的。更正:RCW通过在托管类中将返回类型更改为void来抑制HRESULT代码。因此,S_OK不产生任何返回值,任何非零HRESULT都将被转换
d到托管异常。@Crypt32确定-我一定弄错了。我认为powershell会自动将PreserveSig应用于其RCW,从而导致封送员保留该行为。不,它不会。尽管有自定义的COM自动化实现,PowerShell还是构建在.NET/CLR之上,因此不会保留签名以保持与claasic.NET相同的行为/删除否决票/