`
flyPig
  • 浏览: 137217 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JCE provider管理的问题

    博客分类:
  • Java
阅读更多
现象
两个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类。大功告成。
分享到:
评论

相关推荐

    解决java.lang.SecurityException: JCE cannot authenticate the provider BC问题

    在与银联的对接中,调试过程中报错或使用类似登入加密:java.lang.SecurityException: JCE cannot authenticate the provider BC 进行问题解决,里面包含 bcprov-jdk16-143.jar与bcprov-jdk15-135.jar与具体文件存放...

    org.bouncycastle.jar

    解决org/bouncycastle/jce/provider/bouncycastlepr错误专用。

    Java密码扩展的基础 JCE

    JAVA 加密 JCE Java密码扩展的基础 关于JCE的基础

    JCE cannot authenticate the provider BC相关包

    1.修改 jre/lib/security/java.security文件 security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider, 2.添加2个扩展包到jre/lib/ext目录下:bcprov-jdk15-135.jar bcprov-jdk16-143.jar

    sunjce_provider.jar

    jar包下载地址 : http://www.rsdown.cn/down/164019.html 下载后将sunjce_provider.jar放入webapp/WEB-INF/lib中

    jboss7.1.1下报java.lang.SecurityException: JCE cannot authenticate the provider BC

    NULL 博文链接:https://lwpsoft.iteye.com/blog/2254348

    jce_policy-8 java jce

    JCE,Java Cryptography Extension 1.8, java jce8 java jce

    jce-policy-8 JDK8安装JCE无限强度

    jce_policy-8.zip jar包,jdk,安全,security,oracle官网下载 稍微麻烦 上传供大家方便下载

    JCE包JCE工具库

    Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持

    jce8-jce7.zip

    jce8、jce7下载 jdk8无政策限制权限文件,用于AES加密算法,AES加密扩展包因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件...

    jce-jdk13-139.jar

    jce-jdk13-139.jar是提供给java扩展包,放至jre/lib/ext目录下,并..\jre\lib\security\java.security文件中在配置security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider后使用

    jce_policy文件

    jce_policy-6.zip,jce_policy-8.zip,UnlimitedJCEPolicyJDK7.zip

    Bouncy Castle 的JCE运行包

    免费的JCE提供者。Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。因为 Bouncy Castle 被设计成轻量级的,所以从 J2SE 1.4 到 J2ME(包括 MIDP...

    微信企业号开发JCE6

    微信企业号开发JCE6,JCE包需要根据自己的jdk版本下载,对应JDK6

    JCE(jce_policy-8).zip

    jce_policy-8,JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。 它提供对对称、不对称、块和流密码的加密支持,它还...

    AES192、256位加密解密,jce7,jce8 jdk1.7,jdk1.8

    用于替换jdk里的两个jar,解决无法使用AES192、256位加密解密的问题 jce7,jce8

    joomla JCE 繁体中文语言包

    joomla JCE最新版本2.3.2.4 繁体中文语言包

    jce_policy-8.zip

    jce policy 8 有需要的下载来,分分钟解决你遇到的问题! jce_policy-8,JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现...

    jce6到8对应jar.zip

    jce6到8对应jar.zip,jce6、jce7、jce8对应的jar,详情可以参考https://stackoverflow.com/questions/38203971/javax-net-ssl-sslhandshakeexception-received-fatal-alert-handshake-failure

    JCE 加密、解密算法

    JCE 加密、解密算法

Global site tag (gtag.js) - Google Analytics