我想用iText對PDF文檔進行數字簽名。由於我將使用硬件加密器和JCE提供者,我最終還試圖在我的單元測試中測試擺脫BountyCastle,並暫時使用默認的SUN實現(直到硬件加密器到達)。MakeSignature.signDetached拋出沒有這樣的算法異常(SUN provider&SHA-256)
不過,我得到以下異常,當我運行我的程序:在線程「主要」 java.security.NoSuchAlgorithmException
例外:沒有這樣的算法:SHA256的提供商SUN 在sun.security.jca.GetInstance .getService(GetInstance.java:87) at java.security.MessageDigest上的java.security.Security.getImpl(Security.java:698) sun.security.jca.GetInstance.getInstance(GetInstance.java:206) .getInstance(MessageDigest.java:215) at com.itextpdf.text.pdf.security.DigestAlgorithms.getMessageDigest(DigestAlgorithms.java:159) at com.itextpdf.text.pdf.security.Provide rDigest.getMessageDigest(ProviderDigest.java:61) at SignDoc.signPdf(SignDoc.java:142) at SignDoc.main(com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:130) 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);
正如你所看到的,我只是複製樣品,改變提供者的名稱和電話「新BouncyCastleDigest( )'to'new ProviderDigest(「SUN」)'
偷看iText的源代碼(5.5.1-SNAP SHOT),我發現了以下代碼片段可疑:
MakeSignature.java線142 - 145
的HashAlgorithm = externalSignature.getHashAlgorithm()被調用,然後在
DigestAlgorithms使用。摘要(data,externalDigest.getMessageDigest(hashAlgorithm));
PrivateKeySignature.java線76
由於我使用的PrivateKeySignature,我偷看PrivateKeySignature.java,發現它返回它的私有類成員和的HashAlgorithm這是如何獲得建設中的值(線76) :
這個。 hashAlgorithm = DigestAlgorithms.getDigest(DigestAlgorithms.getAllowedDigests(hashAlgorithm));
DigestAlgorithms.java方法getAllowedDigests()和getDigest()
反過來,getAllowedDigests()如果算法名在allowedDigests哈希映射(2.16.840.1.101.3發現返回了該算法的OID。 4.2.1在我的情況),否則它返回null。
getDigest使用digestNames哈希映射從OID獲取摘要名稱。
但是,對應於OID的digestNames散列映射中的名稱是SHA256,而不是SHA-256。
結果,最終消化名字得到的是「SHA256」,而不是「SHA256」和「SHA256」是導致Sun提供的NoSuchAlgorithm例外。
(我試圖讓直接使用Sun提供的消息摘要的實例,它成功地爲SHA256,但拋出同樣的異常,我彙報這裏SHA256。
這是使用JCE供應商時iText的問題?比BC其他
感激,如果任何人都可以對我的問題提供一些線索
JCE確實沒有將「SHA256」定義爲SHA-256的別名。你能修改iText的digestNames哈希映射,並用2.16.840.1.101.3.4.2.1-> SHA-256替換2.16.840.1.101.3.4.2.1-> SHA256條目嗎? –
感謝您的建議。我認爲這會解決我的問題,但我不確定這是否是正確的方法。無論如何,我會先試一試。 –
如果我按照建議修改映射,則可以成功傳遞MessageDigest.getInstance。但是,當涉及到Signature.getInstance()時,我立即遇到了「沒有這樣的算法」異常(這一次它是期望SHA256withRSA的SHA-256withRSA,我相信)。看起來假設用於摘要的相同算法名稱(例如SHA-256)可以用作簽名算法的前綴是有問題的,因爲算法名稱在提供者(例如SHA256 vs SHA-256)中不一致, 。 –