【问题标题】:bouncycastle + JBoss AS7: JCE cannot authenticate the provider BCbouncycastle + JBoss AS7:JCE 无法验证提供者 BC
【发布时间】:2012-03-02 13:59:15
【问题描述】:

我在我的应用程序中使用 BouncyCastle 进行加密。当我独立运行它时,一切正常。但是,如果我将它放在 webapp 中并部署在 JBoss 服务器上,我会收到以下错误:

javax.servlet.ServletException: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
(...)
root cause
java.lang.Exception: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
(...)
root cause
java.io.IOException: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
    org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
    java.security.KeyStore.load(Unknown Source)

这是导致此错误的部分代码:

    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
    {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    // Read the Private Key
    KeyStore ks = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
    ks.load(new FileInputStream(certificatePath), privateKeyPassword.toCharArray());

和maven依赖:

<dependency>
    <groupId>bouncycastle</groupId>
    <artifactId>bcmail-jdk16</artifactId>
    <version>140</version>
</dependency>

你知道我该如何部署它吗?

【问题讨论】:

    标签: java security jboss bouncycastle jce


    【解决方案1】:

    对于 JBoss AS7,充气城堡需要部署为服务器模块。这取代了早期版本的 server/default/lib 机制(如 Gergely Bacso 的回答中所述)。

    JBoss AS7 使用 jdk1.6+。当使用 JBoss AS7 和 jdk1.6 时,我们需要确保我们使用的是 bcprov-jdk16。

    创建一个 Jboss 模块(一个文件夹 $JBOSS_HOME/modules/org/bouncycastle/main)。 将您希望在全球范围内可用的充气城堡罐放入其中,以及如下所示的module.xml 文件:

    <module xmlns="urn:jboss:module:1.1" name="org.bouncycastle">
        <resources>
            <resource-root path="bcprov-jdk16-1.46.jar"/>
        </resources>
        <dependencies>
            <module name="javax.api" slot="main" export="true"/>
        </dependencies>
    </module>
    

    设置好模块后,您需要使其可用于您的部署。有两种方式:

    1。全局通过standalone.xml

    在 $JBOSS_HOME/standalone/configuration/standalone.xml 中替换

    <subsystem xmlns="urn:jboss:domain:ee:1.0"/>
    

    <subsystem xmlns="urn:jboss:domain:ee:1.0">
        <global-modules>
            <module name="org.bouncycastle" slot="main"/>
        </global-modules>
    </subsystem>
    

    jar 库现在可以在所有应用程序中使用(这将“模拟”添加到类路径中,就像在 jboss 4、5、6 等中一样)

    2。对于特定部署(首选)

    在ear的META-INF/jboss-deployment-structure.xml文件的section下添加一个模块依赖项,eg:

    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
        <deployment>
            <dependencies>
                <module name="org.bouncycastle" slot="main" export="true" />
            </dependencies>
        </deployment>
    </jboss-deployment-structure>
    

    【讨论】:

    • 这背后的原因是什么?如果它是独立运行并且在 JBoss 中运行时需要成为一个模块,为什么它可以工作?模块是否未经验证,但 WEB-INF/lib 中的 jar 是?
    • 说真的,你救了我 :) 我在使用 RSA JSAFE 提供程序时遇到了同样的错误,但现在可以通过这个解决方法摆脱它。非常感谢
    • 在 wildfly-9.0.2.Final 中,BouncyCastle 的模块文件夹已经存在于&lt;HOME&gt;/modules/system/layers/base/org/bouncycastle/main/,因此您只需使其可用于您的部署(全局或单个应用程序)。另请注意,在standalone.xml 中,子系统"urn:jboss:domain:ee" 已经存在,因此您只需将标签&lt;global-modules&gt; 添加到其内容中。
    • @Pino 您能否提供更多详细信息以及初学者的示例。
    • @Awanish 我的评论是对主要答案的一点更新。有关您必须对 Wildfly 的 xml 进行更改的说明,请参阅答案。
    【解决方案2】:

    不要将 bouncy-castle jar 部署为您的 web 应用程序 (WEB-INF/lib) 的一部分。当然,您在编译时需要这个文件,但在 JBOSS 上它应该在这里:

    $JBOSS_HOME/server/default/lib/
    

    而不是

    yourapp/WEB-INF/lib
    

    【讨论】:

    • 为什么会这样?
    • 我在 JDK 1.8 中使用 jboss-eap-6.4 并且我没有服务器目录
    • 这就是我所需要的,我真的很高兴这是公认的答案。 +1
    【解决方案3】:

    但是如果您将服务器从 JBoss 更改为其他服务器(例如 Glassfish),您会遇到同样的问题。
    对我来说更好的解决方案是 jdk 的变化。
    您应该分两步将 Bouncy Castle 添加到您的 java 平台上的安全提供程序:
    1. 将 BC 库(当前为 bcpkix-jdk15on-149.jar、bcprov-jdk15on-149.jar)复制到目录 $JAVA_HOME/jre/lib/ext/
    2. 注册 BC 提供程序:编辑文件 $JAVA_HOME/jre/lib/security/java.security 下划线

    security.provider.1=sun.security.provider.Sun
    

    添加您的 BC 提供者

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

    更改休息提供者的数量。整个提供程序块应类似于:

    security.provider.1=sun.security.provider.Sun
    security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider
    security.provider.3=sun.security.rsa.SunRsaSign
    security.provider.4=sun.security.ec.SunEC
    security.provider.5=com.sun.net.ssl.internal.ssl.Provider
    security.provider.6=com.sun.crypto.provider.SunJCE
    security.provider.7=sun.security.jgss.SunProvider
    security.provider.8=com.sun.security.sasl.Provider
    security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    security.provider.10=sun.security.smartcardio.SunPCSC
    

    现在你必须重新启动 java 服务器。

    【讨论】:

    • 抱歉,您不需要变更提供商。只需在 SunPCSC 提供者下添加下一个提供者数量,例如:security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider BC 提供者不必是第二个。可能是最后一个。
    • @KrzysztofSzewczyk 但是赏金城堡提供者不需要这里的最高提供者,即 1。因为这里的优先级将从 1 到 10。
    【解决方案4】:

    当我放入其他线程时,也可以通过添加以下行以编程方式添加它:

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    来源: jce cannot authenticate the provider bc

    【讨论】:

      【解决方案5】:

      对于那些不想更改服务器级别配置的人,

      <jboss-deployment-structure>  
         <deployment>  
            <resources>  
               <resource-root path="WEB-INF/lib/bcprov-jdk16-1.46.jar" use-physical-code-source="true"/>  
            </resources>  
         </deployment>  
      </jboss-deployment-structure>  
      

      使用 use-physical-code-source 添加充气城堡罐对我有用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多