首先你需要准备你的钥匙:
$ 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库,并可能提供一个如何实现此功能的示例?