我在我的应用程序中使用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>
您知道我该如何部署它?
答案 0 :(得分:44)
对于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>
设置模块后,您需要将其提供给部署。有两种方法:
在$ 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等)
在耳朵的META-INF/jboss-deployment-structure.xml
文件中添加模块依赖项,例如:
<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>
答案 1 :(得分:14)
不要将bouncy-castle jar部署为您的webapp(WEB-INF / lib)的一部分。你当然需要在编译时使用这个文件,但是在JBOSS上它应该在这里:
$JBOSS_HOME/server/default/lib/
而不是
yourapp/WEB-INF/lib
答案 2 :(得分:13)
但是,如果您将服务器从JBoss更改为其他服务器(例如Glassfish),您会遇到同样的问题
对我来说更好的解决方案是改变jdk
您应该通过两个步骤将Bouncy Castle添加到Java平台上的安全提供程序中:
1. 将BC librarys(目前为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服务器。
答案 3 :(得分:0)
当我放入其他一些帖子时,也可以通过以下行添加以编程方式添加:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
答案 4 :(得分:0)
对于那些不想更改服务器级别配置的人,
<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的充气城堡罐对我来说很有效