2

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

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

为此,我构建了一个 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(); }
        }

如何要求用户提供我缺少的密钥?

4

1 回答 1

4

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

我认为您可能错过了公共证书!= 私钥这一点。(我们大多数人都很草率,使用“证书”这个词来指代其中一个(或两个),所以这并不完全令人惊讶)。根据记忆,CryptoAPI 只有一组允许您访问密钥的方法。其中必须有一种“导出为 PFX”的方法,所以如果你真的、真的想要的话,你可以让你的设计工作,但我不建议这样做。(将私钥发送到网络服务器的风险、破坏的不可否认性等)。

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

所以...您可能需要考虑重新构建您的应用程序,以便在上传 PDF 文件之前,在客户端(在您的 ActiveX 控件中)发生 PDF 签名。我想您将需要一个 3rd-party 库来执行此 SO 线程中讨论的签名步骤。

于 2009-01-07T12:17:56.783 回答