BouncyCastle - 为算法设置自定义别名

时间:2016-08-03 09:53:03

标签: java digital-signature bouncycastle

我试图使用Bouncy Castle验证签名摘要。 摘要算法是SHA1。

不幸的是,摘要算法在签名中设置为SHA1WITHRSA(不是摘要算法),而不仅仅是SHA1。

我无能为力。

现在我需要告诉Bouncy Castle在遇到SHA1WITHRSA作为摘要算法时使用SHA1。

是否可以添加导致SHA1摘要算法的别名?

我试过了:

BouncyCastleProvider bcp = new BouncyCastleProvider();
bcp.put("Alg.Alias.MessageDigest.SHA1WITHRSA", "SHA-1");
bcp.put("Alg.Alias.MessageDigest.1.2.840.113549.1.1.5", "SHA-1");
Security.addProvider(bcp);

MessageDigest.getInstance("SHA1WITHRSA", "BC"); // throws an exception
MessageDigest.getInstance("1.2.840.113549.1.1.5", "BC"); // throws an exception

但没有成功.. 我收到java.security.NoSuchAlgorithmException。

完整堆栈在这里:

no such algorithm: SHA1WITHRSA for provider BC
java.security.NoSuchAlgorithmException: no such algorithm: SHA1WITHRSA for provider BC
    at sun.security.jca.GetInstance.getService(GetInstance.java:87)
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
    at java.security.Security.getImpl(Security.java:698)
    at java.security.MessageDigest.getInstance(MessageDigest.java:227)
    at com.company.Main.testAddDigest(Main.java:82)
    at com.company.Main.main(Main.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

和1.2.840.113549.1.1.5相同

no such algorithm: 1.2.840.113549.1.1.5 for provider BC
java.security.NoSuchAlgorithmException: no such algorithm: 1.2.840.113549.1.1.5 for provider BC
    at sun.security.jca.GetInstance.getService(GetInstance.java:87)
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
    at java.security.Security.getImpl(Security.java:698)
    at java.security.MessageDigest.getInstance(MessageDigest.java:227)
    at com.company.Main.testAddDigest(Main.java:95)
    at com.company.Main.main(Main.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

没有这样的摘要算法SHA1WITHRSA,这使得抛出异常是正确的。 但我认为通过添加" put"线条,将添加别名,然后SHA1WITHRSA将被识别为SHA1摘要算法。

更新:当我使用提供商的特定实例时,它正在运行:

MessageDigest.getInstance("SHA1WITHRSA", bcp);

我不确定如何将别名通常添加到BC的所有实例中,而不仅仅是创建的 bcp 变量(BouncyCastleProvider)。如果可能的话。

2 个答案:

答案 0 :(得分:1)

所以,我已经明白了。

我不确定是否有人会遇到这样的情况,但是......

问题在于我正在使用 DSS https://github.com/esig/dss处理数字签名的框架)。 它使用 Bouncy Castle 。 我在特定的PDF上测试它,其摘要算法属性设置为SHA1withRSA(这是不正确的,应该只有SHA1)。 但任务是处理它,因为它设置了正确的值 - SHA1

所以每当遇到SHA1设置为摘要算法时,我都需要告诉弹性城堡使用SHA1withRSA

我不想太多地修改框架代码(理想情况下根本不修改),我当然不想修改任何Bouncy Castle代码。

以下代码解决了这个问题:

BouncyCastleProvider bcp = (BouncyCastleProvider)Security.getProvider("BC");
bcp.addAlgorithm("Alg.Alias.MessageDigest.SHA1WITHRSA", "SHA-1");
bcp.addAlgorithm("Alg.Alias.MessageDigest.1.2.840.113549.1.1.5", "SHA-1");

只要将SHA1WITHRSA1.2.840.113549.1.1.5设置为摘要算法(它们不是!),它就会获得Bouncy Castle提供程序并添加两个别名路由到SHA-1摘要算法。

有人可能会争辩说这样的PDF不应该被验证,但这是不同的事情。

答案 1 :(得分:0)

验证签名只需使用此代码

Signature sig = Signature.getInstance("SHA1withRSA", "BC");
sig.initVerify(publicKey);
sig.update(data)
boolean verifies = sig.verify(sigToVerify);

您将签名算法与摘要算法混淆。 SHA1withRSA是签名算法。这意味着数字签名操作使用SHA1摘要算法执行数据哈希,然后执行RSA加密

因此,java.security.NoSuchAlgorithmException上的MessageDigest.getInstance("SHA1WITHRSA", "BC");是预期的行为,因为SHA1withRSA不是摘要算法

EDITED

如果您想了解签名算法的摘要算法,可以使用BouncyCastle的查找器。

AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
String digestAlgOID = digAlgId.getAlgorithm().getId();
MessageDigest.getInstance(digestAlgOID);