CSR上的签名验证始终返回false(即使签名有效)

时间:2017-01-22 12:02:04

标签: signature pki verify

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

这篇文章涉及我在以下网址创建的初始帖子

Checking the signature of a CSR (X.509 certificate signing request)

但是,我想把这篇文章分开,因为我正在尝试另一种方法。

'目标'是'验证'CSR(PKCS#10 base64格式的X509证书签名请求是否具有有效签名),意味着从CSR获取公钥并验证签名是否正常(例如,检查摘要)使用证书中的公钥解密签名后进行匹配,而不仅仅是检查哈希是否正确形成)

最初,我认为我可以简单地使用 X509enrollment.CX509CertificateRequestPkcs10 COM对象的 ChecjSignature 方法(请参阅上面网址上的初始帖子)

然而,我的初始帖子的贡献者指出,即使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的原因可能是因为在第一个实例中没有使用此 SignData 方法对CSR进行签名,而是使用其他方法。

因此,有人可以帮助我,并告诉我如何验证CSR上的签名是有效的,例如使用CSR中的公钥来检查签名是否有效(例如,使用公钥解密签名,并比较哈希)

先谢谢大家 __AUser

1 个答案:

答案 0 :(得分:0)

我不想评论你在代码中所做的所有事情,因为它是错误的,根本不需要。 IX509CertificateRequestPkcs10界面包含您应该使用的CheckSignature。所以,你的整个代码是四行代码:

#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)

#validate signature
$signatureIsValid = $false
try {
    $RequestComObj.CheckSignature(0x1)
    $signatureIsValid = $true
} catch { }

$signatureIsValid将保留签名有效性状态。