我的公司有一个网络文档管理应用程序,我被指派寻找一种使用用户数字证书对 pdf 文件进行签名的方法。
pdf 的大小可以从几 kb 到超过 100 Mb,这是通过互联网进行的,因此签名必须在网络服务器上进行。
为了做到这一点,我构建了一个 activeX 控件,要求用户选择证书,然后使用 WebClient.UploadData 将证书上传到网页,以字节数组形式发送证书。
在网页上,当我尝试签署 pdf 文档时,出现错误“ key 不存在”。这对我来说并不奇怪,因为当我在选择正确的证书后直接通过 https 连接使用证书时,系统会提示我输入 key 。 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(); }
}
如何要求用户提供我丢失的 key ?
最佳答案
您希望用户将其证书的私钥上传到网络服务器,以便它可以签署 PDF?如果是这样,从安全角度来看,这从根本上被破坏了。
我认为您可能忽略了公共(public)证书!=私钥这一点。 (我们大多数人都很草率,使用“证书”这个词来指代其中一个(或两者),所以这并不完全令人惊讶)。根据内存,CryptoAPI 仅具有一组允许您访问 key 的精选方法。其中必须有一个“导出为 PFX”方法,这样如果您真的非常愿意,就可以使您的设计发挥作用,但我不建议这样做。 (将私钥发送到网络服务器、破坏不可否认性等的风险)。
如果您确实必须在服务器上进行签名[我不太明白您的论点,签名不应在上传中添加太多数据],那么您可能应该考虑多层架构和 key 托管机制。这样您至少可以最大限度地减少一些安全问题(但您仍然会失去不可否认性......并引入其他风险。这里没有免费的午餐)。
所以...您可能需要考虑重新构建您的应用程序,以便在上传 PDF 文件之前在客户端(在您的 ActiveX 控件中)上进行 PDF 签名。我想您将需要一个第三方库来执行签名步骤,如 this SO thread 中所述。 .
关于digital-signature - 对 pdf 进行数字签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/419830/