14

我按照此说明添加 bouncycastle: http: //www.bouncycastle.org/wiki/display/JA1/Provider+Installation 但我还有一个问题。有时当我重新部署我的应用程序时,找不到这个提供程序,所以我的应用程序抛出异常。此问题每 100 次重新部署仅发生一次(可能更少)。当我重新启动我的服务器 - weblogic 然后它再次开始工作。对于为什么会出现此问题的任何建议,我将不胜感激

编辑:

我在上面的链接中使用了这两种方法,因为当我只使用其中一种时它不起作用我添加到 java.security 这个provder,然后在我的类中我注册了这个provder:

static {
    Security.addProvider(new BouncyCastleProvider());
}
4

3 回答 3

26

你可能有一个NoClassDefFoundError. 这是 JSSE 实现的一个已知问题。

这是场景:

  • 您的容器在特定于应用程序的 ClassLoader 中加载充气城堡类
  • 您创建的提供程序实例取决于该类等该 ClassLoader
  • 然后通过顶级 JVM ClassLoader 中的静态字段将提供程序注册到 JRE API
  • 重新部署时,容器丢弃应用程序ClassLoader创建一个新的
  • 由于算法已知,第二个提供者插入失败
  • 使用该算法时,提供程序实例根本无法使用,因为 ClassLoader 已被丢弃
  • 然后唯一的选择是重新启动容器以解决问题。

由于没有针对 undeploy 事件的标准侦听器,因此无法同时触发 JSSE 提供程序删除。

避免该问题的推荐方法是在您的 JVM ClassPath 或容器 ClassPath 中添加充气城堡类。您必须将其从您的应用程序中删除。现在您需要使用静态初始化程序的替代选项注册 BC 提供程序。WebLogic 提供了在服务器启动时触发代码的方法(我使用了服务器启动类),该代码将负责在整个服务器/JVM 生命周期内注册 JSSE 提供程序。

另一种选择是在 JREjava.security文件中添加以下行,其中包含 bouncy castle jar,jre/lib/ext但我不喜欢这种方式,因为更新时它可能会丢失:security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider

因此,应用程序只希望实现存在,添加算法可用性测试以向操作员和用户报告任何问题可能是一个好主意。

于 2012-05-05T23:48:10.763 回答
11

我使用这项工作在 Tomcat 中重新部署应用程序:

public class GenSignCastle {
    BouncyCastleProvider        bcProvider = null;

public GenSignCastle() {
    if ( bcProvider == null ) {
        bcProvider = new BouncyCastleProvider();
        Provider[] providers = Security.getProviders();

        String name = bcProvider.getName();
        Security.removeProvider( name ); // remove old instance

        Security.addProvider( bcProvider );
    }
}
.
.
.
}

有趣的是我必须先删除 BouncyCastleProvider 才能在重新部署后再次使用它。

于 2012-10-30T12:49:00.867 回答
0

通过以下代码和 sun.security.jce 包的使用,可以轻松解决此问题:

ProviderList list = Providers.getFullProviderList();
ProviderList.add(list, new BouncyCastleProvider());
Providers.beginThreadProviderList(list);

该列表将扩展为使用充气城堡提供程序,并且新列表将作为本地线程注入。这可以在 servletfilter 或其他东西中使用。请求完成后可能需要将列表重置为旧值

Providers.endThreadProviderList(this.oldList);
于 2013-09-06T14:05:29.250 回答