【问题标题】:Problem signing PDF with iText, PKCS11 and SHA-256 Algorithm使用 iText、PKCS11 和 SHA-256 算法签署 PDF 时出现问题
【发布时间】:2021-07-26 05:27:49
【问题描述】:

我正在尝试使用 PCKS11(USB 令牌)和 iText 签署 pdf,当我使用 SHA-1 算法时它工作正常,签名有效并且一切正常但是当我将其更改为 SHA256 时签名不是有效,有谁知道为什么?我将把我的代码放在下面:

PKCS11 pkcs11 = PKCS11.getInstance("C:\\Windows\\System32\\example.dll", "C_GetFunctionList", null,false);
long[] slotList = pkcs11.C_GetSlotList(true);
String providerString = "name=*\nlibrary=C:\\Windows\\System32\\example.dll\n" + "slot=" + slotList [0];
SunPKCS11 sunPKCS11 = new SunPKCS11(new ByteArrayInputStream(providerString .getBytes()));
Provider provider = sunPKCS11;

KeyStore keyStore = KeyStore.getInstance("PKCS11", provider);
keyStore.load(null, password);
keyStore.aliases();


Security.addProvider(keyStore.getProvider());

List<String> aliases = Collections.list(keyStore.aliases());
String alias = aliases.get(0);

PrivateKey pk = (PrivateKey)keyStore.getKey(alias,password);

Certificate[] certChain = new Certificate[1];
certChain[0] = signerCert;

PdfReader reader = new PdfReader(inputData);

ByteArrayOutputStream outStream = new ByteArrayOutputStream();        
    
PdfStamper stamper = PdfStamper.createSignature(reader, outStream, '\0',null,true);
    
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();

String fieldName = keyStore.getCertificateAlias(signerCert).replaceAll(".","");

appearance.setVisibleSignature(new Rectangle(420, 10, 70, 85), pageNumber,fieldName);

ExternalSignature es = new PrivateKeySignature(pk, DigestAlgorithms.SHA256,
          keyStore.getProvider().getName());

    ExternalDigest digest = new BouncyCastleDigest();
    
    MakeSignature.signDetached(appearance,
                digest, es,
                certChain, null,
                null, null,
                0, CryptoStandard.CADES);
      
    return outStream.toByteArray();

为什么它适用于 SHA-1 而不是 SHA-2?您认为问题出在哪里?

【问题讨论】:

  • example.dll 支持哪些算法?
  • 它确实支持 SHA256 的哈希值和 SHA256RSA 的签名算法。
  • 请分享一个使用 sha256 签名的示例 pdf 进行分析。
  • 所以我更改了我的哈希值,现在 adobe 显示谁签署了它(因为它曾经是未知的)并且 adobe 还显示哈希算法是 SHA256,它以前没有显示,现在 adobe 说“该文件已被更改,因为......”。我像这样更改了我的哈希: MessageDigest _digest = MessageDigest.getInstance("SHA-256");字节[] 哈希 = _digest.digest(sh); -------------------------------- 我的pdf:file.io/BAvRbgT7RbyB

标签: itext token signature sign pkcs#11


【解决方案1】:

您的签名存在不匹配和错误。

download.pdf

这是您在问题评论中分享的示例文件

文档摘要不匹配

您的 PDF 有符号字节的 SHA-256 哈希值为

9356BCD36F172806A3DCE7F062A66441E7C1DDC9203ABDAA0154A3F19208C8E3

但嵌入的签名容器声称它是

5F892978FF2459157D631809A05F5DBCFCB55800236D2D5C3E4E4D94577012B4

根据您的代码不应该发生。您确定 PDF 是由您问题中的代码创建的吗?或者您是否按照I changed my hash like this 评论的指示以某种方式更改了它并随后创建了示例文档?那么这种差异很可能是由您的更改引起的。

损坏的原始 RSA 签名

解密原始签名字节并删除填充后得到

3031300D0609608648016503040201050004201DC71B824BAA3C7EC6744A0941CFADDAA893E8C1

这是不完整的。它对应于

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
    NULL
  OCTET STRING (32 byte) 1DC71B824BAA3C7EC6744A0941CFADDAA893E8C1XXXXXXXXXXXXXXXXXXXXXXXX

缺少该 XXXXXXXXXXXXXXXXXXXXXXXX 的 12 个字节。

因此,签名设备似乎并不真正支持 SHA256withRSA,至少不与example.dll PKCS#11 驱动程序和SunPKCS11 安全提供程序结合使用。

顺便说一句,八位字节串应该有

EC7FCC5D003DFEC58B0ECB49CEEAD28495FFA8D798A1A88DA6051C1857B971EC

因此,这里看起来是另一个不匹配,1DC71B824BAA3C7EC6744A0941CFADDAA893E8C1 实际上似乎与此值无关。

SHA256.pdf

你能看看这个吗?这个是用itext的库做的,没有改代码。

在这个文件中确实没有哈希不匹配了,只是签名值被截掉了,这里

3031300D0609608648016503040201050004204C8440B547E6A0EFD1489B8F5B5DFDA2DFA45DC1

对应

SEQUENCE (2 elem)
  SEQUENCE (2 elem)
    OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
    NULL
  OCTET STRING (32 byte) 4C8440B547E6A0EFD1489B8F5B5DFDA2DFA45DC1XXXXXXXXXXXXXXXXXXXXXXXX

完整的 OCTET STRING 应该是

4C8440B547E6A0EFD1489B8F5B5DFDA2DFA45DC19048B5E53D468FE6A8E4E973

显然,您的签名设备链、example.dll PKCS#11 驱动程序和来自 JRE 的 SunPKCS11 安全提供程序确实不支持 SHA256withRSA。

【讨论】:

  • 我知道我们的 USB 令牌确实支持 SHA256withRSA,而且我知道人们现在就在这样做,所以是的,谢谢您的帮助。让我先看看这个,如果有什么问题我会回复的。
  • 你能看看这个吗?这个是用 itext 的库制作的,没有更改任何代码。 drive.google.com/file/d/1Hoj_sReCwizlYD1q5pPhy2BqwfoQKLpW/…
  • “我知道我们的 USB 令牌确实支持 SHA256withRSA,而且我知道人们现在就在这样做” - 这就是我写 《至少不支持》的原因结合 example.dll PKCS#11 驱动程序和 SunPKCS11 安全提供程序。》 特别是 SunPKCS11 提供程序远非完美。
  • @Farzanenia 确实,那个文件更好。也许这个文件中的 Adob​​e Reader 会进一步分析,因此最终会查看解密的签名值。因为该值在语法上被破坏,所以它在签名对话框上显示的信息比在发现哈希差异的其他情况下要少。
  • @Farzanenia 你能提供更多关于你的设置的信息吗?您使用哪个 JRE?您到底使用哪个令牌?你有关于它的算法支持的文档吗?
猜你喜欢
  • 2021-09-06
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 2023-03-20
  • 2011-11-17
  • 2017-02-24
相关资源
最近更新 更多