Подпись OpenSSL S/MIME с .NET

Для приложения, которое я разрабатываю, мне нужно создать файл подписи, прежде чем я смогу загружать файлы. Документация объясняет, как это сделать с помощью openssl:

Сначала вам нужно подготовить ключ:

$ openssl pkcs12 -in certificate.pfx -passin pass:xxxxxxxxxx -out pem -clcerts -nokeys
$ openssl pkcs12 -in certificate.pfx -passin pass:xxxxxxxxxx -passout pass:xxxxxx -out key

После чего вы можете подписать любой файл, используя следующий синтаксис:

$ openssl smime -sign -in inputfile -signer pem -inkey key -passin pass:xxxxxx -outform PEM -out signaturefile

Это работает, но я бы предпочел не запускать внешнюю программу только для создания файлов подписи, если это возможно сделать с помощью собственного кода .NET.

Я попытался закодировать это в vb.net и получил следующее:

Public Shared Sub SignFile(ByVal theFilename As String, ByVal theCertFile As String, ByVal thePassword As String, ByVal theDestination As String)
    Dim aCertificate = New X509Certificates.X509Certificate2(theCertFile, thePassword)
    Dim aByteArray = IO.File.ReadAllBytes(theFilename)
    Dim anOid = New System.Security.Cryptography.Oid("1.2.840.113549.1.7.2")
    Dim aContentInfo = New Pkcs.ContentInfo(anOid, aByteArray)
    Dim aSignedCms = New Pkcs.SignedCms(aContentInfo, True)
    Dim aCmsSigner = New Pkcs.CmsSigner(Pkcs.SubjectIdentifierType.IssuerAndSerialNumber, aCertificate)

    aSignedCms.ComputeSignature(aCmsSigner)
    Dim aSignature = Convert.ToBase64String(aSignedCms.Encode())
    IO.File.WriteAllText(theDestination, Convert.ToBase64String(anOutput.ToArray()))
End Sub

Файл, который он создает, не совсем то, что ожидает openssl: мне все еще нужно вставить -----BEGIN PKCS7----- и -----END PKCS7----- и добавить разрывы строк, чтобы строки не были длиннее 65 символов. Но даже после этого подпись, которую я сделал таким образом, недействительна, когда я проверяю с помощью openssl, я получаю следующую ошибку:

5768:error:21071065:PKCS7 routines:PKCS7_signatureVerify:digest failure:.\crypto\pkcs7\pk7_doit.c:1051:
5768:error:21075069:PKCS7 routines:PKCS7_verify:signature failure:.\crypto\pkcs7\pk7_smime.c:410:

Я думаю, что где-то забыл небольшую деталь, но я не могу понять, что именно.

Может ли кто-нибудь помочь мне заставить этот код работать? А если нет, укажите на библиотеку .NET, в которой есть такая функциональность, и, возможно, пример того, как это сделать?


person Mew    schedule 14.10.2010    source источник


Ответы (1)


Какие именно разрывы строк вы добавляете? CRLF или только LF?

У меня похожая проблема с проверкой smime-сообщения. И нахожу причину. OpenSSL изменяет разрывы строк на CRLF (в моем сообщении используется только LF), поэтому содержимое становится отличным от исходного, и проверка дайджеста завершается ошибкой. Может быть, это и ваш случай? К сожалению, я не могу найти решение.

person Donz    schedule 19.10.2010
comment
Я нашел проблему, которая у меня была сейчас: было что-то похожее на это. Я не указал кодировку, когда читал файл. Если я использую кодировку ASCII, она работает. - person Mew; 25.10.2010
comment
Я надеюсь, вы видите это. хотя это старая тема, у меня точно такая же проблема. я попытался открыть входной файл в потоке ascii, закодировав вывод с помощью ascii. Я никогда не получаю тот же результат, что и openssl (с или без ----- BEGIN PKCS7 ----) Если бы вы могли обновить свой вопрос рабочей версией, я был бы признателен. - person ufosnowcat; 22.12.2015
comment
К сожалению, я уже забыл, как решил эту проблему :( Желаю удачи! - person Donz; 13.01.2016