MakeSignature.signDetached抛出No Such Algorithm异常(SUN provider& SHA-256)

时间:2014-03-24 11:11:31

标签: itext sha256

我正在尝试使用iText对PDF文档进行数字签名。由于我将最终使用JCE提供程序的硬件加密器,我也试图在我的单元测试中测试摆脱BountyCastle,而是暂时使用默认的SUN实现(直到硬件加密器到达)。

但是,当我运行程序时出现以下异常:

线程“main”中的异常java.security.NoSuchAlgorithmException:没有这样的算法:SHA256 for provider SUN     at sun.security.jca.GetInstance.getService(GetInstance.java:87)     在sun.security.jca.GetInstance.getInstance(GetInstance.java:206)     at java.security.Security.getImpl(Security.java:698)     在java.security.MessageDigest.getInstance(MessageDigest.java:215)     at com.itextpdf.text.pdf.security.DigestAlgorithms.getMessageDigest(DigestAlgorithms.java:159)     at com.itextpdf.text.pdf.security.ProviderDigest.getMessageDigest(ProviderDigest.java:61)     at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:130)     at SignDoc.signPdf(SignDoc.java:142)     在SignDoc.main(SignDoc.java:182)

最后几行代码如下:

    //ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
    //ExternalDigest digest = new BouncyCastleDigest();
    //ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "SUN");
    ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "SunRsaSign");
    ExternalDigest digest = new ProviderDigest("SUN");
    MakeSignature.signDetached(appearance, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);

如您所见,我只是复制样本并将提供者名称和调用'new BouncyCastleDigest()'更改为'new ProviderDigest(“SUN”)'

偷看iText(5.5.1-SNAPSHOT)的源代码,我发现以下代码片段可疑:

  1. MakeSignature.java第142 - 145行

    调用

    hashAlgorithm = externalSignature.getHashAlgorithm(),然后在

    中使用

    DigestAlgorithms.digest(data,externalDigest.getMessageDigest( hashAlgorithm ));

  2. PrivateKeySignature.java第76行

    由于我正在使用PrivateKeySignature,因此我查看了PrivateKeySignature.java并发现它返回其私有类成员hashAlgorithm,这是它在构造期间获取值的方式(第76行):

    this。 hashAlgorithm = DigestAlgorithms.getDigest(DigestAlgorithms.getAllowedDigests(的HashAlgorithm ));

  3. DigestAlgorithms.java方法getAllowedDigests()和getDigest()

    反过来,如果在allowedDigests哈希映射(在我的例子中为2.16.840.1.101.3.4.2.1)中找到算法名称,则getAllowedDigests()返回算法的OID,否则返回null。

    getDigest使用digestNames哈希映射从OID获取摘要名称。

    但是,与OID对应的digestNames哈希映射中的名称是SHA256,而不是SHA-256。

  4. 因此,最终的摘要名称为“SHA256”而不是“SHA-256”,而“SHA256”导致SUN提供程序中出现NoSuchAlgorithm异常。

    (我尝试直接使用SUN提供程序获取消息摘要实例。它成功用于SHA-256,但抛出了我在这里报告的SHA256相同的异常。

    使用除BC以外的JCE提供程序时,这是iText的问题吗?

    欣赏是否有人可以解释我的问题。

1 个答案:

答案 0 :(得分:0)

作为临时解决方法,我将以下内容添加到PrivateKeySignature.java:

//临时修复 - 删除hashAlgorithm名称中的连字符 // String signMode = hashAlgorithm +“with”+ encryptionAlgorithm;         String signMode = hashAlgorithm.replaceAll(“ - ”,“”)+“with”+ encryptionAlgorithm; //结束临时修复

至少目前它对我有用。我相信,在研究长期解决方案之前,必须研究不同背景下不同算法的标准名称。