带.NET的OpenSSL S / MIME签名

时间:2010-10-14 08:34:08

标签: .net openssl digital-signature smime

对于我正在开发的应用程序,我需要在上传文件之前创建签名文件。它的文档解释了如何使用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库,可能还有一个如何执行此操作的示例?

1 个答案:

答案 0 :(得分:1)

您添加了哪些确切的换行符? CRLF还是LF?

我有类似的问题验证smime消息。我找到了原因。 OpenSSL将换行更改为CRLF(我的消息仅使用LF),因此内容与原始内容不同,摘要检查失败。也许是你的情况呢? 不幸的是我无法找到解决方案。