【问题标题】:C# - Get public key from PDF SignatureC# - 从 PDF 签名中获取公钥
【发布时间】:2017-10-09 08:55:58
【问题描述】:

用例如下:

  1. 用户进入需要出示证书的网站
  2. 如果有效,用户可以下载 PDF 并使用相同的证书对其进行签名
  3. 上传 PDF
  4. 服务器验证 PDF 由提供给网站的相同证书签名。

我被困在第 4 步。我设法从网站和 PDF 中获取了客户端证书公钥,但不一样。公钥是 2048 位的 SHA256 RSA。另外,我正在使用 iTextSharp 处理 PDF 文档。

这是我的代码:

 HttpRequest request = context.Request;

 HttpClientCertificate cert = request.ClientCertificate;

 //get public key from client certificate
 string certKey = BitConverter.ToString(cert.PublicKey).Replace("-", " ")

 //now gets PDF and retrieves public key
 PdfReader pdfreader = new PdfReader("path_to_pdf");


 AcroFields fields = pdfreader.AcroFields;
 AcroFields.Item item = fields.GetFieldItem("Signature1");
 List<string> names = fields.GetSignatureNames();

 foreach (string name in names){
     PdfDictionary dict = fields.GetSignatureDictionary(name);
     PdfPKCS7 pkcs7 = fields.VerifySignature(name);
     Org.BouncyCastle.X509.X509Certificate cert = pkcs7.SigningCertificate;

     //get public key from PDF cert
     SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.GetPublicKey());
     byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
     string serializedPublic = BitConverter.ToString(serializedPublicBytes).Replace("-", " ");
 }

用这个代码certKey和serializedPublic不一样。

【问题讨论】:

  • 它们是根本不同的(关于字节序列部分的长度和整体相似性),还是只是 DER/base64 编码不匹配?此外,当您使用操作系统或 PDF 查看器的证书属性对话框查看这两个证书时,它们是否匹配?
  • 我没有想到。我的代码是从 PDF 中获取的,与我直接从查看器的证书属性中看到的相同,与证书中的不同
  • 我不会怀疑浏览器/iis 往返与the public key...我想您有某种用于测试的自签名证书?显示在签名 PDF 中的公钥是否首先与原始证书匹配?
  • @A77ak 您似乎将证书中的公钥二进制值 (HttpClientCertificate.PublicKey) 与包装公钥的 SubjectPublicKeyInfo 对象 (publicKeyInfo.ToAsn1Object().GetDerEncoded()) 的二进制值进行比较 及其算法。因此,后者可能会包含前者,但不会与前者重合。你可能想试试publicKeyInfo.PublicKeyData.GetBytes()
  • @mkl 它有效!谢谢

标签: c# pdf ssl certificate


【解决方案1】:

在您的代码中进行比较

  • 证书中的公钥二进制值 (HttpClientCertificate.PublicKey) 与
  • 包装公钥及其算法的SubjectPublicKeyInfo 对象 (publicKeyInfo.ToAsn1Object().GetDerEncoded()) 的二进制值。

因此,后者可能会包含前者,但不会与它重合

SubjectPublicKeyInfo 的定义如下:

SubjectPublicKeyInfo ::= SEQUENCE {
    algorithm AlgorithmIdentifier,
    publicKey BIT STRING
}

因此,您应该与包含的公钥的二进制表示进行比较,而不是与完整的SubjectPublicKeyInfo 对象的二进制表示进行比较:

publicKeyInfo.PublicKeyData.GetBytes()

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2011-04-12
    • 2020-02-12
    • 2015-07-17
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多