Проверка подписи на CSR всегда возвращает false (даже если подпись действительна)

Может ли кто-нибудь помочь мне со следующим :)

Это сообщение относится к исходному сообщению, которое я создал по следующему URL-адресу

Проверка подписи CSR (X.509 запрос на подпись сертификата)

Однако я хотел сохранить этот пост отдельно, поскольку пробую альтернативный метод.

«Цель» - «проверить», имеет ли CSR (запрос на подпись сертификата X509 в формате PKCS # 10 base64 действительную подпись), то есть взять открытый ключ из CSR и убедиться, что подпись в порядке (например, проверить соответствие дайджеста после расшифровки). подпись с открытым ключом, хранящимся в сертификате, а не только проверочный хеш, правильно сформирован)

Сначала я думал, что могу просто использовать метод ChecjSignature COM-объекта X509enrollment.CX509CertificateRequestPkcs10 (см. Мое первоначальное сообщение по указанному выше URL-адресу)

Однако участники моего первоначального сообщения указали, что метод, который я использую (особенно для проверки подписи SHA1), пройдет, даже если CSR не был подписан или содержит открытый ключ, не принадлежащий подписи. Другими словами, он просто подтверждал дайджест (хэш), а не подпись.

Я должен указать, что я не разработчик, но хорошо разбираюсь в PowerShell и понимаю концепции C #, поэтому я немного покопался, пытаясь найти подходящий ТИП, у которого был метод, который я мог бы использовать для проверки подписи в CSR (как я мог не могу найти метод KeySignature, упомянутый автором в моем исходном сообщении)

Поэтому, покопавшись, я написал следующий код PowerShell, но он всегда возвращает FALSE, когда я знаю, что CSR действителен и подписан SHA1.

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

читая статью MSDN о ТИПЕ System.Security.Cryptography.RSACryptoServiceProvider, в ней говорится, что метод VerifyData используется для проверки данных, подписанных с помощью SignData , поэтому я думаю, что причина, по которой мой код всегда возвращает FALSE, может быть в том, что CSR не был подписан с использованием этого метода SignData в первом экземпляре, а скорее каким-то другим методом.

Поэтому может кто-нибудь любезно помочь мне и показать мне, как проверить, что подпись на CSR действительна, например. использовать открытый ключ в CSR, чтобы проверить действительность подписи (например, расшифровать подпись с помощью открытого ключа и сравнить хэши)

Заранее всем спасибо __AUser


person AUser    schedule 22.01.2017    source источник


Ответы (1)


Я не хочу комментировать все, что вы делаете в коде, потому что это неправильно и совсем не нужно. Интерфейс 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 будет содержать статус действительности подписи.

person Crypt32    schedule 22.01.2017
comment
Привет Crypt32 и большое спасибо за то, что нашли время ответить - person AUser; 22.01.2017
comment
Извините, я хотел добавить, изначально я использовал метод CheckSignature, но я был проинформирован в предыдущем сообщении, которое я сделал здесь: stackoverflow.com/questions/41765074/, что это не обязательно будет проверять подпись поскольку он допускает Null, и поэтому только хеш, а не подписанный хеш также будет считаться действительным, поэтому я искал альтернативу (я, возможно, неправильно понял) для ответов на мой предыдущий пост. Не могли бы вы прояснить это для меня? еще раз спасибо - person AUser; 22.01.2017
comment
На самом деле, думая об этом (еще не пробовал), если у вас был CSR, который не был подписан, и вы пытались декодировать с помощью $ RequestComObj.InitializeDecode ($ CSR, 6), я предполагаю, что это не удастся декодировать, поскольку он не был подписан и имеются в виду CSR быть подписанным, если это так, то ответ на CheckSignature (0x1) в порядке. В любом случае я отвлекся, еще раз спасибо за вашу помощь :) - person AUser; 22.01.2017
comment
$RequestComObj.InitializeDecode($CSR,6) будет декодировать как подписанные, так и неподписанные запросы. Когда вы передаете флаг 0x1 в CheckSignature, он выдаст исключение, если подпись недействительна или имеет нулевую подпись. - person Crypt32; 22.01.2017