【问题标题】:Checking the signature of a CSR (X.509 certificate signing request)检查 CSR 的签名(X.509 证书签名请求)
【发布时间】:2017-06-05 12:38:05
【问题描述】:

有人可以帮我解决以下问题

我想检查 CSR(X509 证书签名请求)上的签名是 有效的 我相信我知道该怎么做(如下),但不确定我的理解是否正确,如果有人可以检查/更正/确认我的方法,将不胜感激。

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

所以在 PowerShell 中我执行以下操作

$CSR = 获取内容 c:\temp\csr.txt –raw $RequestComObj = 新对象 -ComObject X509enrollment.CX509CertificateRequestPkcs10 $RequestComObj.InitializeDecode($CSR,6)

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

AllowedKeySignature = 0x1 AllowedNullSignature = 0x2

从我到目前为止阅读/尝试的内容来看,我可以将这两个值之一传递给构造函数,SHA1 为 0x1,SHA2 为 0x2(例如 SHA256) 因此我的问题是,如果我有一个使用 SHA1 签名的 CSR,并且我想检查这个 SHA1 签名是否有效,我的脚本的最后一部分应该如下所示?

$RequestComObj.CheckSignature(0x1)

或者可能只是

$RequestComObj.CheckSignature(1)

如果 CSR 使用 SHA2 签名,我会使用

$RequestComObj.CheckSignature(0x2)

或者可能只是

$RequestComObj.CheckSignature(2)

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

上面说的对吗?例如对我认为的检查签名有效

谢谢大家

__AUser


我正在编辑我的问题以回复以下答案(由于太大而无法作为评论发布)

你好 vcsjones 和 Crypt32

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

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

请问我上面的理解正确吗?

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

还有 你上面提到的而不是使用 CheckSignature() 我应该使用 KeySignature

当我查看上面 $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 等中使用它。

非常感谢再次感谢

__AUser

【问题讨论】:

    标签: c# powershell certificate x509 pki


    【解决方案1】:

    根据我迄今为止阅读和尝试的内容,我可以将以下两个值之一传递给构造函数:SHA1 为 0x1,SHA2 为 0x2(例如 SHA256)。

    这并不完全正确。 CheckSignature 接受一个参数,表示允许什么样的签名,必要时可以按位组合。

    如果使用了NullSignature,那么您根本不会验证签名,正在验证的只是 CSR 的摘要。如果使用KeySignature,则根据用于验证 CSR 的公钥验证 CSR 的签名。

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

    【讨论】:

    • 关于 .NET 和 PowerShell 的最后一段完全不正确。
    • 解释一下:CertEnroll 是一组 COM 接口。 CLR (PS, .NET) 不能直接与 COM 世界通信,COM 世界也不能直接与 CLR 通信。他们使用代理:COM Callable Wrapper (CCW) 进行通信:COM -> CLR 和 Runtime Callable Wrapper (RCW) 进行通信 CLR -> COM。 RCW 通过将返回类型更改为void 来抑制 S_OK 代码,并且非零 HRESULT 转换为托管异常。因此,OP的解释是完全正确的。
    • 更正:RCW 通过在托管类中将返回类型更改为 void 来抑制 HRESULT 代码。因此,S_OK 不会产生任何返回值,任何非零 HRESULT 都会被转换为托管异常。
    • @Crypt32 好的——我一定是弄错了。我认为 powershell 会自动将 PreserveSig 应用于其 RCW,这会导致编组器保留该行为。
    • 不,它没有。尽管其自定义 COM 自动化实现,PowerShell 构建在 .NET/CLR 之上,因此不保留签名以保持与 claasic .NET 相同的行为。 /删除了反对票/
    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2014-09-30
    • 2017-11-28
    相关资源
    最近更新 更多