考虑系统password的安全,眼下大多数系统都不会把password以明文的形式存放到数据库中。

一把会採取下面几种方式对password进行处理

password的存储

“编码”存储

Shiro 提供了 base64和 16
进制字符串编码/解码的 API支持,方便一些编码解码操作。 Shiro内部的一些数据的存储/表示都使用了
base64和 16 进制字符串。

以下两端代码分别对其进行演示

Stringstr = "hello"; 

Stringbase64Encoded = Base64.encodeToString(str.getBytes()); 

Stringstr2 = Base64.decodeToString(base64Encoded); 

Assert.assertEquals(str,str2);

通过如上方式能够进行 base64编码/解码操作

Stringstr = "hello"; 

Stringbase64Encoded = Hex.encodeToString(str.getBytes()); 

Stringstr2 =newString(Hex.decode(base64Encoded.getBytes())); 

Assert.assertEquals(str,str2);

通过如上方式能够进行 16
进制字符串编码/解码操作

Hash存储

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储password之类的数据,常见的散列算法如 MD5、SHA等。一般进行散列时最好提供一个 salt(盐),比方加密password“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,能够到一些
md5解密站点非常easy的通过散列值得到password“admin”,即假设直接对password进行散列相对来说破解更easy,此时我们能够加一些仅仅有系统知道的干扰数据,如username和 ID(即盐);这样散列的对象是“password+username+ID”,这样生成的散列值相对来说更难破解。

Stringstr = "hello"; 

Stringsalt = "123"; 

Stringmd5 =new Md5Hash(str, salt).toString();//还能够转换为  toBase64()/toHex()

如上代码通过盐“123”MD5散列“hello”。另外散列时还能够指定散列次数,如 2次表示:md5(md5(str)):“new
Md5Hash(str, salt, 2).toString()”

Stringstr = "hello"; 

Stringsalt = "123"; 

Stringsha1 =new Sha256Hash(str, salt).toString();

使用 SHA256
算法生成对应的散列数据,另外还有如 SHA1、SHA512算法。

Shiro 还提供了通用的散列支持:

Stringstr = "hello"; 

Stringsalt = "123"; 

//内部使用MessageDigest 

StringsimpleHash =new SimpleHash("SHA-1", str, salt).toString();

通过调用 SimpleHash 时指定散列算法,其内部使用了 Java的 MessageDigest
实现。为了方便使用,Shiro提供了 HashService,默认提供了 DefaultHashService实现

DefaultHashServicehashService =new DefaultHashService(); //默认算法 SHA-512 

hashService.setHashAlgorithmName("SHA-512");

hashService.setPrivateSalt(newSimpleByteSource("123"));//私盐,默认无

hashService.setGeneratePublicSalt(true);//是否生成公盐,默认false 

hashService.setRandomNumberGenerator(new  SecureRandomNumberGenerator());//用于生成公盐。默认就这个

hashService.setHashIterations(1);//生成 Hash 值的迭代次数

HashRequestrequest =new HashRequest.Builder() 

.setAlgorithmName("MD5").setSource(ByteSource.Util.bytes("hello"))

.setSalt(ByteSource.Util.bytes("123")).setIterations(2).build();

Stringhex =hashService.computeHash(request).toHex();

加密存储

Shiro 还提供对称式加密/解密算法的支持,如 AES、Blowfish等;当前还没有提供对非对称加密/解密算法支持,未来版本号可能提供。

AES 算法实现:

AesCipherServiceaesCipherService =new AesCipherService(); 

aesCipherService.setKeySize(128);//设置 key 长度

//生成 key 

Keykey=aesCipherService.generateNewKey(); 

Stringtext = "hello"; 

//加密

StringencrptText =

aesCipherService.encrypt(text.getBytes(),key.getEncoded()).toHex(); 

//解密

Stringtext2 = 

newString(aesCipherService.decrypt(Hex.decode(encrptText),key.getEncoded()).getBytes()); 

Assert.assertEquals(text, text2);

password的验证

使用“password的存储”章节中当中一种存储方式存储password之后,接下来就是登陆时password的验证.

该过程主要涉及到两个问题:

(1)    让Shiro知道数据库中存储的password是通过什么方式存储的?

能够在指定比較器时进行设置

(2)    让Shiro知道怎样比对数据库与登录时的password?

Shiro主要通过CredentialsMatcher的子类来实现password的对照,Shiro已经实现了比較常见的Matcher,比如Md5CredentialsMatcher,Sha256CredentialsMatcher等等,假设Shiro提供的Matcher不能满足需求,还能够自己定义Matcher.

Spring集成Shiropassword验证实例

本小节以Spring集成Shiro为基础,介绍怎样使用MD5对password进行加密,加入password加密功能须要经过下面三步

保存password

作为password的数据源头,首先要确保在password保存时就使用MD5加密

在Spring的Controller相应的方法中,使用下面方法保存password

@RequestMapping("/setting/user/add")
public String addUser(@Valid User user, BindingResult result, Map<String, Object> model,
@RequestParam(value = "action") String action) {
String cryptedPwd = new Md5Hash(user.getPwd()).toString();
user.setPwd(cryptedPwd);
userService.saveUser(user);
return "redirect:/setting/user/" + user.getName();
}

配置Matcher

当数据库中存的是MD5形式的password后,就要告诉shiro怎样对登陆时输入的password进行对照,在这里採用默认的HashedCredentialsMatcher作为比較器

Shiro-config.xml配置例如以下

<!—在自己定义的Realm中配置Matcher,并指定加密算法-->

         <beanid="customerRealm" class="com. test.security.CustomerRealm">

                   <propertyname="credentialsMatcher">

                            <beanclass="org.apache.shiro.authc.credential.HashedCredentialsMatcher">

                                     <propertyname="hashAlgorithmName" value="MD5" />

                            </bean>

                   </property>

         </bean>

password校验

对于CustomerRealm而言,不须要关心password是怎样被匹配的,仅仅须要将用户输入的password传入AuthenticationInfo对象中就可以

@Override

  protectedAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)

     throws AuthenticationException {

   // 获取基于username和password的令牌,authcToken是从LoginController里面//currentUser.login(token)传过来的

   UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

   User user = userService.findUserByName(token.getUsername());

    if(null != user) {

     AuthenticationInfo authcInfo =

         new SimpleAuthenticationInfo(user.getName(), user.getPwd(),user.getName());

     this.setSession(GCloudConstant.CURRENT_USER,user.getName());

     return authcInfo;

    }else {

     return null;

    }

  }

将 Shiro 作为一个许可为基础的应用程序 五:password加密/解密Spring应用的更多相关文章

  1. 一个很奇怪的问题,程序没有改动加密参数应该也没有变化.但是两次的加密结果却不一致.md5加密问题

    从图上我们看出20160803的加密结果是AAEBA9C578EA522215EAE76AFCAF250.时间是9.4分 现在我们再看这个同样的加密地址与时间结果却是另一种 31672B16..... ...

  2. SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能

    SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 第一步:配置web.xml <!-- 配置Shiro过滤器,先让Shiro ...

  3. MVVM之旅(1)创建一个最简单的MVVM程序

    这是MVVM之旅系列文章的第一篇,许多文章和书喜欢在开篇介绍某种技术的诞生背景和意义,但是我觉得对于程序员来说,一个能直接运行起来的程序或许能够更直观的让他们了解这种技术.在这篇文章里,我将带领大家一 ...

  4. 一个完整的Installshield安装程序实例-转

    一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(一)---基本设置一 前言 Installshield可以说是最好的做安装程序的商业软件之一,不过因为功能的太过于强大,以至于 ...

  5. [转]一个完整的Installshield安装程序实例

    @import url("http://files.cnblogs.com/files/go-jzg/vs.css"); --> Installshield安装程序实例—基本 ...

  6. 一个简单的P2P传输程序

    写了一个简单的P2P传输程序,在P2P的圈子中传输文件,不过为了简便,这个程序没有真正的传输文件,只是简单的判断一下文件的位置在哪里.这个程序可以处理当有一个peer闪退的情况,在这种情况下,剩下的p ...

  7. 第一个 Asp.Net vNext 应用程序

    要说免费的虚拟主机的话,最好的服务商应该就是Microsoft Azure(不是Windows Azure由世纪互联运营),提供免费的1GB .NET/Java/Python/Php空间,日流量有限制 ...

  8. 学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序

    学习ASP.NET MVC系列: 学习ASP.NET MVC(一)——我的第一个ASP.NET MVC应用程序 学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器 学习ASP ...

  9. IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序

    前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...

随机推荐

  1. golang channel初次接触

    goroutine之间的同步 goroutine是golang中在语言级别实现的轻量级线程,仅仅利用go就能立刻起一个新线程.多线程会引入线程之间的同步问题,经典的同步问题如生产者-消费者问题,在c, ...

  2. 安装centos7注意事项

    1,安装centos7注意1和l的区分 2,每一次对/boot/grub2/或者/boot/grub或者/etc/grub/下的文件修改一定要重新编译配置文件sudo grub2-mkconfig - ...

  3. 数据结构C语言版 弗洛伊德算法实现

    /* 数据结构C语言版 弗洛伊德算法  P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...

  4. 互联网创业十问?good(快速迭代、把握核心用户应对抄袭,不需要把商业模式考虑完备,4种失败的信号,失败者没资格说趁着年轻...)

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:曹政链接:https://www.zhihu.com/question/20264499/answer/28168079来源: ...

  5. synapse socket总结一:服务器模型

    synapse (http://synapse.ararat.cz/doku.php)的源码简洁明了,属于轻量级的阻塞式socket通讯组件包,更多的功能需要自己基于它的基础上去封装实现.相对于ind ...

  6. hackyviewpager有什么用

    继承于viewpager 可以和photoView一起使用,实现相册图片的左右滑动,放大缩小,等 package davidwang.tm.view; import android.content.C ...

  7. 基于visual Studio2013解决C语言竞赛题之0415特殊对数

       题目 解决代码及点评 这道题也是锻炼for循环,在for循环中遍历所有可能的数,然后再判断该数是不是有这样的性质 /********************************* ...

  8. Global文件(修正篇)

    什么是Global文件 Global.asax文件俗称为一个类,继承于Httpapplication类.位于应用程序根目录下.也可称为应用程序文件. 概述: Global文件是可选的,一般在创建应用程 ...

  9. QT序列化操作(比较复杂和完善)

    应用需求: 在网盘开发过程中有这样一个需求,即对文件版本进行控制,即记录文件版本的更替信息,这里说的更替信息仅仅是记录不同时刻的文件变化,即文件的增.删.改.重命名等操作.在每个待监控的目录下都会保存 ...

  10. Qt状态机框架

    The State Machine Framework 状态机框架提供了用于创建和执行状态图的类.概念和符号是基于Harel的Statecharts: A visual formalism for c ...