簡體   English   中英

如何在簽署 PDF 時以編程方式輸入 X509Certificate2 證書的 PIN(在 C# 中)

[英]How to enter PIN for X509Certificate2 certificate programmatically when signing a PDF (in C#)

我正在使用 syncfusion pdf 對 pdf 文件進行數字簽名。 在他們的網站上,他們有一個外部簽署 PDF 的示例。 我稍微更改了示例,因此可以從 windows 證書存儲中選擇證書。 所選證書需要 PIN,以便彈出對話框。 function Signature_ComputeHast 是普通的 C# 代碼。 如何在下面的代碼中以編程方式輸入 PIN?

原始示例: https://help.syncfusion.com/file-formats/pdf/working-with-digitalsignature#externally-sing-a-pdf-document

       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();
        }

您將需要在 Windows 上使用支持硬件安全模塊的 RSACryptoServiceProvider 或 RSACng cng(在 .NET 核心中)類以更高的粒度級別。 您可以使用包含密碼的參數創建適當 class 的新實例,如下所示:

        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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM