C# 以证书签署PDF文件
我正在尝试使用Syncfusion对PDF文档进行数字签名。(用于生成pdf文档的库)C# 以证书签署PDF文件,c#,pdf,certificate,syncfusion,signing,C#,Pdf,Certificate,Syncfusion,Signing,我正在尝试使用Syncfusion对PDF文档进行数字签名。(用于生成pdf文档的库) 整个文档,而不仅仅是字段。 我对签名或证书一无所知我知道证书属于HSM类型,所以我使用了: 它在我的开发PC上工作,但在生产中不工作。找不到证书,但在签署文档时会导致: CryptographicException: Unknown error „-1073741823“ at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer
整个文档,而不仅仅是字段。 我对签名或证书一无所知
我知道证书属于HSM类型,所以我使用了: 它在我的开发PC上工作,但在生产中不工作。找不到证书,但在签署文档时会导致:
CryptographicException: Unknown error „-1073741823“ at System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner signer, Boolean silent)
我的代码:
using Syncfusion.Licensing;
using Syncfusion.Pdf;
using Syncfusion.Pdf.Graphics;
using Syncfusion.Pdf.Parsing;
using Syncfusion.Pdf.Security;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace SyncfusionTest3
{
class Program
{
public static X509Certificate2 infoCertifikat = null;
static void Main(string[] args)
{
var store = new System.Security.Cryptography.X509Certificates.X509Store(StoreLocation.LocalMachine);
string thumbprint = "9F.."; //Production
store.Open(OpenFlags.ReadOnly);
foreach (var mCert in store.Certificates)
{
if (mCert.Thumbprint.ToUpper().Equals(thumbprint.ToUpper()))
infoCertifikat = mCert;
}
if (infoCertifikat == null)
{
Console.WriteLine("404 Certificate not found");
Console.ReadKey();
return;
}
string licenceKey = "LicenceKey";
SyncfusionLicenseProvider.RegisterLicense(licenceKey);
using (var pdfDoc = new PdfLoadedDocument("document.pdf"))
{
pdfDoc.DocumentInformation.Creator = "Me";
pdfDoc.DocumentInformation.Author = "Naxi";
PdfCertificate pdfCertificate = new PdfCertificate(infoCertifikat);
//Normal signing
//Syncfusion.Pdf.Security.PdfSignature signature1 = new Syncfusion.Pdf.Security.PdfSignature(pdfDoc, pdfDoc.Pages[0], pdfCertificate, "DigitalSign");
//External signing becouse of HSM type of certificate
Syncfusion.Pdf.Security.PdfSignature signature1 = new Syncfusion.Pdf.Security.PdfSignature(pdfDoc, pdfDoc.Pages[0], null, "DigitalSign");
signature1.ComputeHash += Signature_ComputeHash1;
signature1.Bounds = new System.Drawing.RectangleF((6 * 25.4f / 0.352777778f), (9.3f * 25.4f / 0.352777778f), 65, 25);
signature1.ContactInfo = "Contact";
signature1.LocationInfo = "World";
signature1.Reason = "I want it";
PdfStandardFont font = new PdfStandardFont(PdfFontFamily.Helvetica, 3.8f);
float row_height = 4.2f;
signature1.Appearance.Normal.Graphics.DrawString("Digitally Signed by " + signature1.ContactInfo, font, PdfBrushes.Black, 0, row_height * 1);
signature1.Appearance.Normal.Graphics.DrawString("Reason: " + signature1.Reason, font, PdfBrushes.Black, 0, row_height * 2);
signature1.Appearance.Normal.Graphics.DrawString("Location: " + signature1.LocationInfo, font, PdfBrushes.Black, 0, row_height * 3);
signature1.Appearance.Normal.Graphics.DrawString((DateTime.Now).ToString(), font, PdfBrushes.Black, 0, row_height * 4);
pdfDoc.Save("document_signed.pdf");
pdfDoc.Close(true);
}
}
private static void Signature_ComputeHash1(object sender, PdfSignatureEventArgs ars)
{
//Get the document bytes
byte[] documentBytes = ars.Data;
SignedCms signedCms = new SignedCms(new ContentInfo(documentBytes), detached: true);
var cmsSigner = new CmsSigner(infoCertifikat);
//Set the digest algorithm SHA256
//cmsSigner.DigestAlgorithm = new Oid("1.3.6.1.4.1.311.10.3.12"); //Document signing – just tried
//cmsSigner.DigestAlgorithm = new Oid("1.2.840.113549.1.1.11"); //SHA256RSA
//cmsSigner.DigestAlgorithm = new Oid("1.2.840.113549.1.1.5"); //SHA1RSA
//cmsSigner.DigestAlgorithm = new Oid("1.3.14.3.2.26"); //SHA1
cmsSigner.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1"); //SHA256
cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly; //Without this it throws CryptographicException: A certificate chain could not be bulit to a trusted root authority. (only in production)
signedCms.ComputeSignature(cmsSigner);
//Embed the encoded digital signature to the PDF document
ars.SignedData = signedCms.Encode();
}
}
}
我尝试使用不同的算法。(用代码注释)但我不知道该用哪一个。我正在为平台目标x64构建它,因为没有它会导致:
CryptographicException: The keyset is not defined. at System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner signer, Boolean silent, DafeCryptoProvHandle)
生产过程中使用了经过审查的证书:
我在开发上的证书有一个关键用法:签名文档,这在生产中是不存在的。 或者增强的密钥使用缺少什么 谢谢你的建议 更新: 所以,我以不同的方式迈出了一小步,看起来很有希望,但不是穆奇
cmsSigner.DigestAlgorithm = new Oid("1, 3, 36, 3, 3, 1, 1"); //RSA + SHA1
这导致:加密异常:对象标识符的格式不正确。在SignedCms.Sign(…)
================ Certificate 0 ================
Serial Number: ...
Issuer: ...
NotBefore: ...
NotAfter: ...
Subject: ...
Non-root Certificate
Cert Hash(sha1): 9f
Key Container = ...
Provider = Luna enhanced RSA and AES provider for Microsoft Windows
Private key is NOT exportable
ERROR: Could not verify certificate public key against private key
Revocation check skipped -- server offline
Certificate is valid
确保证书安装在正确的存储中(代码显示
StoreLocation.LocalMachine
)。因此,让我们首先检查存储中的证书是否正常,以及密钥是否关联和可访问
运行以下命令列出并验证存储中的所有证书:
certutil -verifystore MY
输出应显示如下内容:
================ Certificate X ================
Serial Number: ...
Issuer: ...
NotBefore: ...
NotAfter: ...
Subject: ...
Non-root Certificate
Cert Hash(sha1): ...
Key Container = ...
Unique container name: ...
Provider = ...
Private key is NOT exportable
Signature test passed
...
这将向您显示私钥关联及其提供程序,并将创建一个签名以检查密钥是否可访问
因此,请确保为运行命令的用户以及您的应用程序授予访问密钥的权限。您可能需要通过阅读HSM用户手册或联系负责人(内部或制造商支持)来澄清这一点
您的SignedCms
代码看起来不错-对于测试,请尽可能保持简单(无摘要算法),并以小步前进
编辑
此外,当然,您需要信任您的证书。这意味着证书信任链已安装到证书存储
证书可在此处找到:
- 运行
certlm.msc
- 需要通过右键单击目录并选择所有任务和*导入,将其添加到受信任的根证书颁发机构*
- 需要通过右键单击目录并选择所有任务和*导入,将其添加到中间证书颁发机构*
eventvwr.msc
)在certutil崩溃后,并提供错误消息的详细信息?是的,没有什么特别的,只是崩溃。在我的测试应用程序中,它发生在MSVCP.dll中。HSM提供程序承认,证书存在问题。我们将重新安装所有服务器。这可能结束。
================ Certificate X ================
Serial Number: ...
Issuer: ...
NotBefore: ...
NotAfter: ...
Subject: ...
Non-root Certificate
Cert Hash(sha1): ...
Key Container = ...
Unique container name: ...
Provider = ...
Private key is NOT exportable
Signature test passed
...