我公司有一个网络文档管理应用程序,我被指派找到一种用用户数字证书签署pdf文件的方法。

pdf可以从几kb到100Mb以上,这是通过互联网进行的,因此签名 必须 在网络服务器上进行。

为了做到这一点,我构建了一个activeX控件,要求用户选择证书,然后使用WebClient.UploadData将证书作为字节数组发送到网页。

在网页上,当我尝试签署pdf文档时,我收到错误“密钥不存在”。这对我来说并不奇怪,因为当我在选择合适的证书后直接通过https连接使用证书时,我会提示输入密钥。 activeX不会发生这种情况。

这就是我从用户那里获得证书的方式:

private static X509Certificate2 PickCertificate()
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            try
            {
                store.Open(OpenFlags.ReadOnly);

                // pick a certificate from the store
                X509Certificate2 cert = X509Certificate2UI.SelectFromCollection(store.Certificates, "Title", "Message", X509SelectionFlag.SingleSelection)[0];

                // show certificate details dialog
                X509Certificate2UI.DisplayCertificate(cert);
                store.Close();
                return cert;
            }
            finally { store.Close(); }
        }

如何让用户提供我错过的钥匙?

有帮助吗?

解决方案

您希望用户将其证书的私钥上传到网络服务器,以便签署PDF吗?如果是这样,从安全角度来看,这基本上已被打破。

我想你可能已经错过了公共证书!=私钥。 (我们大多数人都很草率,并使用“证书”这个词来指代那些事情中的任何一个(或两个),所以这并不完全令人惊讶。从内存开始,CryptoAPI只有一组选择的方法,允许您访问密钥。必须有“出口为PFX”。其中的方法,所以你可以让你的设计工作,如果你真的,真的想,但我没有办法推荐这个。 (将私钥发送到网络服务器的风险,破坏的不可否认性等等)。

如果你真的必须在服务器上签名[我真的不明白你的论点,签名不应该为上传添加太多数据],那么你应该考虑一个多层架构和一个密钥托管机制。这样你至少可以减少一些安全问题(但你仍然会失去不可否认性......并引入其他风险。这里没有免费午餐。)

所以......您可能需要考虑重新设计应用程序,以便在上载PDF文件之前在客户端(在ActiveX控件中)发生PDF签名。我想你需要一个第三方库用于签名步骤,如这个SO线程所述

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top