【发布时间】:2017-01-22 12:02:04
【问题描述】:
有人可以帮我解决以下问题吗:)
这篇文章与我在以下 URL 创建的初始帖子有关
Checking the signature of a CSR (X.509 certificate signing request)
但是,我想将这篇文章分开,因为我正在尝试另一种方法。
“目标”是“验证”CSR(PKCS#10 base64 格式的 X509 证书签名请求是否具有有效签名),这意味着从 CSR 获取公钥并验证签名是否正常(例如检查摘要使用证书中保存的公钥解密签名后匹配,而不仅仅是检查哈希是否格式正确)
最初我认为我可以简单地使用 X509enrollment.CX509CertificateRequestPkcs10 COM 对象的 ChecjSignature 方法(请参阅我在上述 URL 上的初始帖子)
然而,我最初帖子的贡献者指出,即使 CSR 未签名或包含不属于签名的公钥,我使用的方法(特别是用于 SHA1 签名验证)也会通过。换句话说,它只是确认摘要(哈希)而不是签名有效。
我应该指出我不是开发人员,但我可以使用 PowerShell 并了解 C# 的概念,因此我进行了一些挖掘,试图找到一个合适的 TYPE,它有一个方法可以用来验证 CSR 上的签名,(因为我找不到贡献者在我的原始帖子中提到的 KeySignature 方法)
因此,经过一番挖掘,我编写了以下 PowerShell 代码,但当我知道 CSR 有效且已签名 SHA1 时总是返回 FALSE
<# contents of CSR file
-----BEGIN NEW CERTIFICATE REQUEST-----
MIID9zCCAt8CAQAwHTEbMBkGA1UEAwwSd3d3MDEuZmFicmlrYW0uY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlQdqVHQgzd1uJ9MFb935Vfyg1Y1m
ZXn4OMwJudOhEzx7m1+4C8lDOXn5hglHG0FFad+KkLok/GcAzdc2iwBOholJ2MYP
XCnfkJLYXHLRj+CKRvhCHWJOXkQQQ0apdXh1MhiDBD/BIKqmMm54XLFhZqjQiNeI
VHFb9GS06Ps/xuOWzqY54xSM/047nzYNU50FrTHuBCiqtJtHpKtdrCWyhWi7was0
noCx/XGm6g8nVnzPTQCSeAPp6mSt4kSMtdoVZYg1n5pmMW+QYAero/UWrbNp1Wlk
pUH4s96H6pUrbF7RIkXpCwWocxBHAXVcMst2HYvwstAETxvqeKTOvVEEAQIDAQAB
oIIBkzAcBgorBgEEAYI3DQIDMQ4WDDEwLjAuMTQzOTMuMjBCBgkrBgEEAYI3FRQx
NTAzAgEJDA9ERVNLVE9QLU41OEkzMzEMFERFU0tUT1AtTjU4STMzMVx1c2VyDAdj
ZXJ0cmVxMHIGCisGAQQBgjcNAgIxZDBiAgEBHloATQBpAGMAcgBvAHMAbwBmAHQA
IABSAFMAQQAgAFMAQwBoAGEAbgBuAGUAbAAgAEMAcgB5AHAAdABvAGcAcgBhAHAA
aABpAGMAIABQAHIAbwB2AGkAZABlAHIDAQAwgboGCSqGSIb3DQEJDjGBrDCBqTAO
BgNVHQ8BAf8EBAMCBaAweAYJKoZIhvcNAQkPBGswaTAOBggqhkiG9w0DAgICAIAw
DgYIKoZIhvcNAwQCAgCAMAsGCWCGSAFlAwQBKjALBglghkgBZQMEAS0wCwYJYIZI
AWUDBAECMAsGCWCGSAFlAwQBBTAHBgUrDgMCBzAKBggqhkiG9w0DBzAdBgNVHQ4E
FgQUBMisP2saqKPzBdEj1TyUC4jQR78wDQYJKoZIhvcNAQEFBQADggEBADCBGPbL
mGx89pgELT/wwZmdDuN3ci+3oaA1wfUHgqVmIXLbadnx41Z1j/30tZKxO7YE86b6
Sx7jXFusiH+sAseAqWkgF00vJ2RDNaTE8iDn/cQlxELtUxYn75F7jVmWMgUgAIH6
CLjf34ssNp+9tywKl1/72QC0ixaL4qoaJaLF2ezPB/UZ3rVV5FHsonAnd5oDiKwz
lws0e3zf3EZpcd2FzgxTqhYAEYFdvCBHvjSCvHg0x7L1e2J3pPRMKv6nSN9wfvxM
UC72lcn9skWOrnpCt24vn1E3BI16QWD27xZpx4z+LfbJwKGkf987vIcIipRZCAco
dcvCmbzEjf1/xso=
-----END NEW CERTIFICATE REQUEST-----
#>
#get contents of CSR file as a Base64 String (e.g. the -raw parameter returns string rather than array)
$CSR = Get-Content c:\TEMP\csr.txt -raw
#create an instance of the X509enrollment.CX509CertificateRequestPkcs10 class COM object
$RequestComObj = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10
#decode the CSR (returns COM object)
$RequestComObj.InitializeDecode($CSR,6)
#get public key from CSR COM object (returns Base64 string)
$PublicKey = $RequestComObj.PublicKey.EncodedKey()
#get public key from CSR COM object (returns Base64 string)
$Signature = $RequestComObj.Signature()
#convert CSR Base64 string to Byte array
$CSRBytes = [Byte[]][Char[]]$CSR
#convert PublicKey Base64 string to Byte Array
$PublicKeyBytes = [Byte[]][Char[]]$PublicKey
#convert Singature Base64 string to Byte Array
$SignatureBytes = [Byte[]][Char[]]$Signature
#create an instance of the System.Security.Cryptography.RSACryptoServiceProvider class
$RSACryptoServiceProvider = [System.Security.Cryptography.RSACryptoServiceProvider]::Create()
$RSACryptoServiceProvider
#get the OID for the SHA1 algirithm
$SHA1_OID = [System.Security.Cryptography.CryptoConfig]::MapNameToOID('SHA1')
#attempt to verify signature of CSR
$RSACryptoServiceProvider.VerifyData($CSRBytes,$SHA1_OID,$SignatureBytes)
阅读关于 System.Security.Cryptography.RSACryptoServiceProvider TYPE 的 MSDN 文章,其中指出 VerifyData 方法用于验证使用 SignData 签名的数据 方法,因此,我认为我的代码总是返回 FALSE 的原因可能是因为 CSR 没有在第一个实例中使用此 SignData 方法进行签名,而是使用其他一些方法。
因此,有人可以帮助我,并告诉我如何验证 CSR 上的签名是否有效,例如使用 CSR 中的公钥检查签名是否有效(例如用公钥解密签名,并比较哈希)
提前谢谢大家 __AUser
【问题讨论】: