Bouncycastle提供程序无法找到所需算法的类。

27

我正在尝试使用BouncyCastle使用公钥加密文件。 我已经以编程方式注册了提供程序:

Security.addProvider(new BouncyCastleProvider());

我成功地创建了公钥对象。

但是,在使用PGPEncryptedDataGenerator和该密钥加密文件时,出现了ClassNotFound异常。

尽管我确定我有它的jar包,但似乎在运行时提供程序找不到此类。

我正在Tomcat上运行应用程序。使用Maven处理依赖项 - 我放置的bouncy castle jar包是bcpg,bcprov,bcmail,bctsp。我尝试使用1.4和1.6版本都没有成功。我使用Maven插件中的“依赖层次结构”和POM中的排除来确保项目中没有多个版本的Bouncy Castle。

这是堆栈跟踪:

org.bouncycastle.openpgp.PGPException: exception encrypting session key
        at org.bouncycastle.openpgp.PGPEncryptedDataGenerator.open(Unknown Source)
        at org.bouncycastle.openpgp.PGPEncryptedDataGenerator.open(Unknown Source)
.....(web application stack trace and uninteresting stuff).....
Caused by: java.security.NoSuchAlgorithmException: No such algorithm: ElGamal/ECB/PKCS1Padding
        at javax.crypto.Cipher.getInstance(DashoA13*..)
        at org.bouncycastle.openpgp.PGPEncryptedDataGenerator$PubMethod.addSessionInfo(Unknown Source)
        ... 42 more
Caused by: java.security.NoSuchAlgorithmException: class configured for Cipher(provider: BC)cannot be found.
        at java.security.Provider$Service.getImplClass(Provider.java:1268)
        at java.security.Provider$Service.newInstance(Provider.java:1220)
        ... 44 more
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.JCEElGamalCipher$NoPadding
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
        at java.security.Provider$Service.getImplClass(Provider.java:1262)
3个回答

23

您遇到了BouncyCastle安全提供程序的安装问题,您需要执行以下操作之一:

  • 将BouncyCastle添加到JRE/JDK $JAVA_HOME/jre/lib/security/java.security 文件中作为提供程序(确保将其添加到运行时使用的JRE中,例如,如果您安装了多个JRE/JDK)

例如:

security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider

(并重新编号下面的安全提供程序-不要将其作为最高优先级提供程序)。

  • 或者您可以以编程方式添加BouncyCastle,就像您之前试图做的那样,但在这种情况下,安全策略 $JAVA_HOME/jre/lib/security/java.policy 应该是“无限制”的(您可能可以从Java主页下载无限制的策略文件)。

1
你能为每个方法提供更多的技术细节吗? - Sam
你需要将所有BouncyCastle的JAR文件放在lib/ext目录下吗?更改后是否需要重新启动任何内容以使更改生效? - Sam
技术细节:除了编辑文本文件之外,在第一种方法的情况下,几乎不需要做其他事情。 - egbokul
7
对于任何遇到此问题的人,以下是简要概述: 不要在程序中以编程方式添加Bouncy Castle。在$JAVA_HOME/jre/lib/security/java.security中定义它,并将Bouncy库放在jre/lib/ext中。如果您正在运行Tomcat并使用Maven,则可以使用Maven将依赖范围设置为“提供”,重新部署具有这些设置的应用程序,并重新启动Tomcat以便它可以“查看”您放置在lib/ext中的新库。 - Sam
个人经验是,在 java.policy 文件中将 BC 插入到第二个位置(而不是最后一个位置)会更好。 - Pavel Vlasov
显示剩余3条评论

10

在我的情况下,使用BC(Bouncy Castle)时,一开始能够正常使用,但后来出现ClassNotFoundException异常。我重新启动了Tomcat,然后就可以正常使用了。

我认为如果您像开发时经常这样重新部署应用程序,它就会停止工作。 JNI(Java Native Interface)也会受到这个问题的影响。

在我们的情况下,这不是一个问题。我们从未在测试和生产系统上重新部署过。我更喜欢将JAR文件与应用程序一起打包,而不是手动将其复制到容器lib目录中。


1
当我重新加载我的Web应用程序后,出现了java.security.NoSuchAlgorithmException错误。但是当我重启Tomcat后,这个问题就解决了。 - dave
我之前一直在使用Websphere,突然间出现了下面的异常。我尝试了4-5个小时,但是无法理解是什么原因导致的。在尝试了所有的选项后,我重启了Websphere,然后它开始正常工作了。java.lang.ClassNotFoundException: org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$PBKDF2with8BIT - undefined

3

你需要在你的lib文件夹中添加javapns.jar和bcprove-jdk15on-1.47.jar文件。

import javapns.Push;

import org.apache.log4j.BasicConfigurator;

public class SendPushNotification {

  public static void main(String[] args) {

    try {

        BasicConfigurator.configure();
        Push.alert("Hello World!", "Cetificate.p12", "password", false,
                "mydeviceToken");

    } catch (Exception e) {
        System.out.println(e);
    }

   }

}

不需要javapns.jar来编写需要bcprov的代码。(虽然实际情况是相反的,但javapns的使用与问题无关。) - anre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接