`

跟开涛学shiro遇到异常Cannot find any provider supporting AES/CBC/PKCS5Padding【解决】

阅读更多

在学习shiro中遇到很多问题,网上资料较少,只有硬啃英文,但demo太少,不好理解。ITeye博客中开涛对编写了比较全的系列教程

跟我学Shiro目录贴

,提供给大家学习,感谢开涛。

在学习到第十三章 RememberMe——《跟我学Shiro》的时候,有一个问题困扰了我2天,给开涛留言,至今未回复,功夫不复有心人,今天早上得到了解决。

问题描述:

1.按照开涛的测试过程

测试:
1、访问http://localhost:8080/chapter13/,会跳转到登录页面,登录成功后会设置会话及rememberMe Cookie;
2、关闭浏览器,此时会话cookie将失效;
3、然后重新打开浏览器访问http://localhost:8080/chapter13/,还是可以访问的;
4、如果此时访问http://localhost:8080/chapter13/authenticated.jsp,会跳转到登录页面重新进行身份验证。

 

测试本章节demo时发现记住我功能不能实现,仔细思考为什么呢?

2.查看cookie,仅生成了sid的cookie,没有生成rememberMe,究竟哪里出了问题?

3.debug跟踪源码

public Subject login(Subject subject, AuthenticationToken token) throws 
AuthenticationException {
        AuthenticationInfo info;
        try {
            info = authenticate(token);
        } catch (AuthenticationException ae) {
            try {
                onFailedLogin(token, ae, subject);
            } catch (Exception e) {
                if (log.isInfoEnabled()) {
                    log.info("onFailedLogin method threw an " +
                            "exception.  Logging and propagating original 
AuthenticationException.", e);
                }
            }
            throw ae; //propagate
        }

        Subject loggedIn = createSubject(token, info, subject);

        onSuccessfulLogin(token, info, loggedIn);

        return loggedIn;
    }

 从onSuccessfulLogin(token, info, loggedIn);这里一路逛追,直至

 

private javax.crypto.Cipher newCipherInstance(boolean streaming) throws 
CryptoException {
        String transformationString = getTransformationString(streaming);
        try {
            return javax.crypto.Cipher.getInstance(transformationString);
        } catch (Exception e) {
            String msg = "Unable to acquire a Java JCA Cipher instance using " +
                    javax.crypto.Cipher.class.getName() + ".getInstance( \"" +
 transformationString + "\" ). " +
                    getAlgorithmName() + " under this configuration is required 
for the " +
                    getClass().getName() + " instance to function.";
            throw new CryptoException(msg, e);
        }
    }

 在这里 return javax.crypto.Cipher.getInstance(transformationString);抛出异常:

org.apache.shiro.crypto.CryptoException: Unable to acquire a Java JCA Cipher

 instance using javax.crypto.Cipher.getInstance( "AES/CBC/PKCS5Padding" ).

 AES under this configuration is required for the org.apache.shiro.crypto.

AesCipherService instance to function.
	......
Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider

 supporting AES/CBC/PKCS5Padding
	at javax.crypto.Cipher.getInstance(Cipher.java:523)
	at org.apache.shiro.crypto.JcaCipherService.newCipherInstance
(JcaCipherService.java:408)
	... 28 more

4.不明觉历!!!!!!!!!!!难道是开涛的代码有问题??还是故意设置了障碍要大家学习(实践证明这些假设都是错的)

5.网上查了很多资料,未果,分析源码CookieRememberMeManager继承了AbstractRememberMeManager,在AbstractRememberMeManager中的构造方法中默认初始化了加密算法与设置了默认的cipherKey

 public AbstractRememberMeManager() {
        this.serializer = new DefaultSerializer<PrincipalCollection>();
        this.cipherService = new AesCipherService();
        setCipherKey(DEFAULT_CIPHER_KEY_BYTES);
    }

 

问题的结点可以定在cipherService的实现或者cipherKey的配置上,但很快排除了这一假设。

6.回顾第5章节的例子

@Test
	public void testAesCipherService() {
		CipherService cipherService = new AesCipherService();
		// aesCipherService.setKeySize(128);//设置key长度
		// byte[] key = aesCipherService.generateNewKey().getEncoded();
		// String base64 = Base64.encodeToString(key);
		byte[] key = Base64.decode("4AvVhmFLUs0KTA3Kprsdag==");
		System.out.println("key2==" + key.toString());
		System.out.println(Base64.encodeToString(key));
		// 生成key
		// Key key = aesCipherService.generateNewKey();

		String text = "hello";
		System.out.println(new String(text.getBytes()));
		// 加密
		try {
			String encrptText = cipherService.encrypt(text.getBytes(
), key).toHex();
			System.out.println("encrptText==" + encrptText);
			// 解密
			String text2 = new String(cipherService.decrypt(
Hex.decode(encrptText), key).getBytes());
			System.out.println("text2==" + text2);
			Assert.assertEquals(text, text2);
		} catch (CryptoException e) {
			e.printStackTrace();
		}
	}

 不断调试,右击项目属性--Properties----Java Build Path-----Libraries----JRE System Libraries,修改为jdk_1.7.0.01_x86(名称是添加jre时自定义的),测试代码,可以运行通过。原来是jdk的设置不正确!!!!我的电脑上安装了x86,x64的jdk,平时使用的是x64的版本。

7.以为大功告成,可是……使用jetty启动、使用tomcat启动,测试失败!啊啊啊!!要疯的节奏

8.难道是环境变量也要改过来?修改jdk环境变量%JAVA_HOME%为x86的版本之后,测试成功!终于松了一口气。

记录此问题的解决过程,虽然仅仅是jdk版本的问题,可能安装了x86 jdk的人永远不会遇到,但是还是费了我不少功夫去排除道道屏障,最终拨云见日。

结论:

1.shiro的加密使用javax.crypto.Cipher.getInstance获得实例,不支持64bit的jdk

2.遇到这个错误不用改环境变量,可以通过配置运行时的jre解决

   a)tomcat:window->perferences->server->runtime Env--Edit Server--修改JRE为x86版本

   b)jetty:Debug As--Run Configurations---JRE修改为x86版本

(此问题为电脑上同时安装了x64、x86版本jdk的伙伴记录)

 

 

 

3
4
分享到:
评论
5 楼 aionbo 2017-06-29  
我按你们说的也改成x86了,但还是报同样的错
4 楼 纵观全局 2016-08-06  
完美解决,谢谢
3 楼 Blod123 2016-06-19  
看来 还是一步步跟,我也跟了,只是没有跟到你那么深
2 楼 Long_yuan 2015-06-30  
楼主精神可嘉
1 楼 java-lxm 2015-06-30  
学习了

相关推荐

    《跟我学Shiro》- 张开涛.txt

    ***txt文件中含有下载地址** 《跟我学Shiro》- 张开涛,PDF版本,带目录,清晰。 示例源代码:https://github.com/zhangkaitao/shiro-example; 加qun 231889722 探讨Spring/Shiro技术。

    跟我一起学shiro 张开涛

    书中可能涵盖如何在Spring Boot、Spring MVC等常见框架中整合Shiro,以及如何解决实际开发中遇到的问题,比如跨域问题、单点登录等。 总的来说,《跟我一起学Shiro——张开涛》这本书是学习Shiro的宝贵资料,不仅...

    开涛学shiro

    简单了解shiro流程原理和使用,对项目中的使用指导还是很有意义的

    高版本AES-GCM模式加密的Shiro漏洞利用1

    Shiro框架在高版本中更换了加密算法,从AES-CBC换成了AES-GCM,这导致了之前的exp不能用于新版Shiro的加密解密调用。 在高版本Shiro中,AesCipherService类使用AES-GCM模式进行加密,设置了加密模式为GCM, Padding...

    [资料][Java]跟我学Shiro教程_Java跟我学Shiro教程_shiro_

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常方便地开发出足够安全的应用。...阅读 "[资料][Java]跟我学Shiro教程.pdf",你将得到更详细的步骤指导和实践案例。

    跟我学Shiro

    通过《跟我学Shiro》.pdf,你将学习到如何创建 Realm 实现数据源连接、配置 Shiro 安全框架、处理登录和登出逻辑、实现权限控制以及在实际项目中部署和调优 Shiro。 10. **最佳实践** 学习 Shiro 的过程中,了解...

    跟我学shiro

    - **背景**:Apache Shiro 是一个强大且易于使用的 Java 安全框架,为开发者提供了一站式的安全解决方案,涵盖了认证、授权、加密以及会话管理等多个方面。 - **特性**: - **易用性**:相比其他复杂的安全框架,...

    shiro教程 跟我学Shiro教程

    "跟我学Shiro教程"资源包包含了全面学习Shiro所需的重要材料,包括文档和实践示例。 首先,我们来看《Apache_Shiro参考手册中文版.pdf》。这本书籍详细介绍了Shiro框架的各个组件和使用方法。通过阅读,你可以了解...

    跟我学Shiro教程.rar

    "跟我学Shiro教程"这个资源显然是为了帮助学习者深入理解并掌握Shiro的核心概念和实际应用。 在Shiro的认证服务中,其主要目标是确认用户身份。这通常涉及用户登录过程,其中用户提供的凭证(如用户名和密码)被...

    跟我学Shiro-java开发+spring开发

    《跟我学Shiro-java开发+spring开发》是一个深入学习Java安全框架Shiro和Spring集成的教程,旨在帮助开发者掌握这两个关键技术在实际项目中的应用。Shiro是一个强大的且易用的Java安全框架,提供了认证、授权、加密...

    第十七章 OAuth2集成——《跟我学Shiro》 - 开涛的博客 - ITeye技术网站2

    在《跟我学Shiro》的第十七章中,作者开涛介绍了如何集成OAuth2,使用Apache Oltu作为OAuth2服务端的实现。实现中涉及以下关键部分: 1. **依赖**:引入了`authzserver`(授权服务器依赖)和`resourceserver`(资源...

    跟我学Shiro教程及其课程分章节源码

    Apache Shiro是一个强大易用的Java安全框架,...我找了一版 跟我学Shiro教程PDF,里面讲的很详细.里面还附带了每个章节的源码.值得你收藏哟!饮水思源——原文出自:http://jinnianshilongnian.iteye.com/blog/2049092

    跟我学Shiro教程 pdf

    《跟我学Shiro》PDF完结版下载, Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

    跟我学 Shiro - v1.1.rar

    Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Sp ring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所 ...

Global site tag (gtag.js) - Google Analytics