现象
两个module A和B分别采用了infosec的不同版本,虽然classloader已经保证了A和B所依赖的资源均可以正确的load, 并且成功地newInstance() 或者new构造,但是仍然出现ClassCastException、ClassNotFoundException、NoSuchMethodException等异常
问题分析
Security vendor有infosecurity,bouncycastle等好几种,在JCE框架里面都被抽象成Provider,每个供应商实现抽象类Provider,JVM会管理这些Provider.同一个JVM中,不同的module依赖了同一个Provider(eg.Infosecurity)的不同版本,如果Provider之间是不兼容的,尽管通过ClassLoader机制让不通的module分别load到了各自对应的Provider,但是因为JCE管理Provider的方式,它们的name完全相同,B的会把A的infosec Provider给覆盖。这会导致A使用了B的provider,仍然会产生可恶的ClassCastException、NoSuchMethodException等。
问题探索
一步步的看Provider是被管理使用的。首先从MessageDigest开始,一般我们这么使用
MessageDigest md = MessageDigest.getInstance("SHA-1","INFOSEC");
//or
MessageDigest md = MessageDigest.getInstance("MD5");
看看里面怎么做的,很明显,找到多个取第一个。
public static MessageDigest getInstance(String paramString)
throws NoSuchAlgorithmException
{
try
{
Object[] arrayOfObject = Security.getImpl(paramString, "MessageDigest", (String)null);
if (arrayOfObject[0] instanceof MessageDigest)
{
localObject = (MessageDigest)arrayOfObject[0];
((MessageDigest)localObject).provider = ((Provider)arrayOfObject[1]);
return localObject;
}
Object localObject = new Delegate((MessageDigestSpi)arrayOfObject[0], paramString);
((MessageDigest)localObject).provider = ((Provider)arrayOfObject[1]);
return localObject;
}
catch (NoSuchProviderException localNoSuchProviderException)
{
throw new NoSuchAlgorithmException(paramString + " not found");
}
}
然后就到Security类了
static Object[] getImpl(String paramString1, String paramString2, String paramString3)
throws NoSuchAlgorithmException, NoSuchProviderException
{
if (paramString3 == null)
return GetInstance.getInstance(paramString2, getSpiClass(paramString2), paramString1).toArray();
return GetInstance.getInstance(paramString2, getSpiClass(paramString2), paramString1, paramString3).toArray();
}
getSpiClass方法暂时忽略掉,这里有2个分支,为了方便直接看第二个分支。
public static Instance getInstance(String paramString1, Class paramClass, String paramString2, String paramString3)
throws NoSuchAlgorithmException, NoSuchProviderException
{
return getInstance(getService(paramString1, paramString2, paramString3), paramClass);
}
public static Provider.Service getService(String paramString1, String paramString2, String paramString3)
throws NoSuchAlgorithmException, NoSuchProviderException
{
if ((paramString3 == null) || (paramString3.length() == 0))
throw new IllegalArgumentException("missing provider");
Provider localProvider = Providers.getProviderList().getProvider(paramString3);
if (localProvider == null)
throw new NoSuchProviderException("no such provider: " + paramString3);
Provider.Service localService = localProvider.getService(paramString1, paramString2);
if (localService == null)
throw new NoSuchAlgorithmException("no such algorithm: " + paramString2 + " for provider " + paramString3);
return localService;
}
可以看到,最终的是在Providers所管理的ProviderList里面保存所有的Provider,而且保存的方式是以paramString3参数,也就是"INFOSEC"去获取Provider。而相同vendor的不同版本Provider的Name是完全一样的,区别是version不同,这里印证了猜想:
不同的Provider因为相同的name而被认为是同一个Provider而产生的同名覆盖
如何解决。Security,Providers,ProviderList是java core包的类,不可轻易改动,否则后果很难估计。我在这里采用的方法比较简陋,从Providers类做改动,直接覆盖Providers类的管理逻辑:针对当前Thread的classloader的类型做判断,如果是SystemClassLoader,则使用自己的Provider管理逻辑,否则还是使用之前的管理方式。
完成后对Providers重新打包成providers.jar,加入启动参数-Xbootclasspath/p:/data/overwrite/providers.jar以覆盖rt.jar中的Providers类。大功告成。
分享到:
相关推荐
综上所述,解决“jboss7.1.1下报java.lang.SecurityException: JCE cannot authenticate the provider BC”问题涉及对Java加密机制、Bouncy Castle库以及JBoss服务器的深入理解。通过正确配置和调试,这个问题是可以...
在Java平台上,安全性是不可或缺的一部分,而`sunjce_provider.jar`则是Java加密技术的核心组件,它作为Java Cryptography Extension (JCE) 的一部分,提供了丰富的加密算法和服务。本文将详细探讨`sunjce_provider....
在Java平台上,安全性是至关重要的一个环节,而`sunjce_provider.jar`则是Java安全体系中的关键组件,它扮演着Java Cryptography Extension (JCE) 提供者的角色。JCE是Java平台的一个扩展,用于支持加密、密钥管理和...
1. **加密服务提供者**:JCE通过服务提供者接口(Service Provider Interface, SPI)来引入不同的加密实现。开发者可以选择不同的服务提供者,如SunJCE(Sun的JCE实现)或其他第三方提供者。 2. **加密算法**:JCE...
JCE是Java平台的标准扩展,用于加密、解密、密钥管理和消息摘要等功能。SunJCE提供了一些高级的加密算法,如RSA、DES、AES等,以及SSL/TLS协议支持。 描述中提到的“找不到com.sun.crypto.provider.SunJCE()”错误...
"sunjce_provider.zip"是一个包含SUNJCE提供商实现的压缩包,主要文件为"sunjce_provider.jar",这个JAR文件包含了用于加密、解密、数字签名和密钥管理等操作的类和接口。 1. **Java Cryptography Architecture ...
`sunjce_provider`是Java Cryptography Extension (JCE)的一部分,JCE是Java标准版(Java SE)的一个组件,扩展了Java的安全性,提供了强大的加密功能。`sunjce_provider`提供了一种实现这些加密算法的方式,开发者...
总的来说,【cyassl-provider-0.1.zip】是一个与SSL相关的组件包,它提供了自定义的JCE和JSSE实现,帮助开发者在Java应用中实现更高效、更安全的SSL/TLS网络通信。通过理解和使用这个组件,开发者能够更好地控制和...
1. **理解X Server:** 在Linux环境中,X Server是一个重要的组成部分,它负责渲染图形界面并管理用户的交互操作。如果X Server无法正常启动,将会严重影响用户体验。 2. **字体配置:** 在Linux系统中,字体的...
Java Crypto Extension (JCE)是Java平台中处理加密操作的核心组件,它支持用户自定义加密算法实现,这些实现被称为JCE Provider。Bouncy Castle是一个流行的JCE Provider,因为它提供了丰富的加密算法实现,包括椭圆...
1. **cryptix-jce-provider.jar**:这是Cryptix的Java Cryptography Extension (JCE) 提供者。JCE是Java平台的一部分,提供加密、哈希和消息认证码(MAC)算法。Cryptix JCE Provider扩展了标准Java的加密功能,增加...
Java JCE是Java标准版(Java SE)的一部分,提供了一组接口和类来处理加密、解密、密钥生成和管理等任务。JCE包含了一组默认的加密提供商,但它们可能不支持所有加密算法或者在某些情况下性能较低。这时,可以引入...
而Provider API则是一个JCA/JCE的实现,可以无缝集成到Java的加密框架中,提供大量的加密算法和协议支持。 二、JAR包内容解析 "Bouncycastle_jar"压缩包内包含的是Bouncy Castle库的Java类库文件,这些文件通常以....
import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import java.security.Security; // 添加BouncyCastleProvider Security.addProvider(new BouncyCastleProvider()); //...
为了提供更高级别的安全服务,JCE还允许开发者通过实现Provider接口来添加自定义的加密算法或安全服务。Java SDK通常已经内置了一些知名的Provider,如SunJCE和IBMJCE,但开发者也可以选择第三方Provider,如Bouncy ...
2. **Bouncy Castle Provider**:Bouncy Castle Provider是Java加密库的实现,提供了大量的加密算法,包括非对称加密、对称加密、哈希函数、数字签名等,并且支持SSL/TLS协议。 3. **SSL/TLS协议**:SSL/TLS协议...
在JCE中,Provider是用于提供加密算法实现的实体。例如,文档中提到了SUN Provider和Bouncy Castle Provider,它们都是一些第三方的Provider实现。Bouncy Castle是一个流行的开源加密库,提供了丰富的加密算法实现,...
Bouncy Castle 提供了丰富的加密算法、密钥生成器、证书处理以及PKI(Public Key Infrastructure,公钥基础设施)的相关功能,极大地扩展了Java标准加密库(JCE,Java Cryptography Extension)的功能。 Bouncy ...