如何在签署PDF(C#)时以编程方式输入X509Certificate2证书的PIN



我使用syncfusion pdf对pdf文件进行数字签名。在他们的网站上,他们有一个外部签署PDF的例子。我稍微修改了这个示例,以便可以从windows证书存储中选择证书。所选证书需要PIN,因此会弹出一个对话框。Signature_ComputerHast函数是一个简单的C#代码。如何在下面的代码中以编程方式输入PIN?

原始示例:https://help.syncfusion.com/file-formats/pdf/working-with-digitalsignature#externally-单页文件

private static X509Certificate2 SelectCertificate()
{
// Selecte certificate from store
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection selectedCertificate = (X509Certificate2Collection)collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false);// (X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, true);
selectedCertificate = X509Certificate2UI.SelectFromCollection(
store.Certificates,
"Certficates",
"Select a certificate for signing the document",
X509SelectionFlag.SingleSelection);
return selectedCertificate[0];
}

void Signature_ComputeHash(object sender, PdfSignatureEventArgs arguments)
{
//Get the document bytes
byte[] documentBytes = arguments.Data;
SignedCms signedCms = new SignedCms(new ContentInfo(documentBytes), detached: true);
//Compute the signature using the specified digital ID file and the password
X509Certificate2 certificate = SelectCertificate();
var cmsSigner = new CmsSigner(certificate);
//Set the digest algorithm SHA256
cmsSigner.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");
signedCms.ComputeSignature(cmsSigner);
//Embed the encoded digital signature to the PDF document
arguments.SignedData = signedCms.Encode();
}

您需要使用RSACryptoServiceProvider或RSACng-cng(在.NET核心中(类,这些类在Windows上支持更高级别的硬件安全模块。您可以创建一个适当类的新实例,其中包含如下密码的参数:

if(certificate.PrivateKey is RSACryptoServiceProvider rsa) {
if(rsa.CspKeyContainerInfo.HardwareDevice) {
CspParameters cspParams = new CspParameters(1, rsa.CspKeyContainerInfo.ProviderName,
rsa.CspKeyContainerInfo.UniqueKeyContainerName) {
KeyPassword = certPassword,
Flags = CspProviderFlags.NoPrompt
};
byte[] signedCMSBytes = new RSACryptoServiceProvider(cspParams).SignData(documentBytesDigest);
}
}

据我所知,在签名之前,您需要创建documentBytes摘要的哈希摘要,并将其与所需的已验证属性一起放入PKCS#7中。之后,您将需要向CMS添加任何未经验证的属性。就我个人而言,所有这些都是使用Bouncy Castle完成的。但我们必须使用MS SSC与操作系统交互,才能访问HSM。有一种潜在的方法可以用SSC类来完成这一切。顺便说一句,certPassword是一个SecureString。

相关内容

最新更新