Shiro笔记(四)编码/加密

一、编码和解码

     //base64编码、解码
@Test
public void testBase64(){
String str="tang";
byte[] encode = Base64.encode(str.getBytes());
System.out.println("Encode result:"+encode);
System.out.println("The decode result:"+Base64.decodeToString(encode));
} //16进制字符串编码,解码
@Test
public void testHex(){
String str="Java";
char[] encode = Hex.encode(str.getBytes());
System.out.println("encode result:"+encode);
System.out.println("decode result:"+new String(Hex.decode(encode)));
}

二、散列算法

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5,SHA等。

     //MD5算法
@Test
public void testMD5(){
String str="king";
String salt="salt1";
String s = new Md5Hash(str, salt).toString();
System.out.println("MD5 code: "+s);
} //SHA算法
@Test
public void testSHA(){
String str="king";
String salt="salt1";
String s = new Sha256Hash(str, salt).toString();
System.out.println("SHA code: "+s);
}

三、PasswordService/CredentialMatcher

Shiro 提供了 PasswordService 及 CredentialsMatcher 用于提供加密密码及验证密码服务。

 public interface PasswordService {

     //输入明文密码得到密文密码
String encryptPassword(Object plaintextPassword) throws IllegalArgumentException; /**
* @param submittedPlaintext a raw/plaintext password submitted by an end user/Subject.
* @param encrypted the previously encrypted password known to be associated with an account.
* This value is expected to have been previously generated from the
* {@link #encryptPassword(Object) encryptPassword} method (typically
* when the account is created or the account's password is reset).
* @return {@code true} if the {@code submittedPlaintext} password matches the existing {@code saved} password,
* {@code false} otherwise.
* @see ByteSource.Util#isCompatible(Object)
*/
boolean passwordsMatch(Object submittedPlaintext, String encrypted);
}
 public interface CredentialsMatcher {

     //匹配用户输入的 token 的凭证(未加密)与系统提供的凭证(已加密)
boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info); }

Shiro 默认提供了 PasswordService 实现 DefaultPasswordService;CredentialsMatcher 实现
PasswordMatcher 及 HashedCredentialsMatcher(更强大)。

应用实例:

 public class MyRealm extends AuthorizingRealm{

     private PasswordService passwordService;

     public void setPasswordService(PasswordService passwordService) {
this.passwordService = passwordService;
} protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
} protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
return new SimpleAuthenticationInfo("tang",
passwordService.encryptPassword("123456"),getName());
}
}

HashedCredentialsMatcher应用:

 public class MyRealm2 extends AuthorizingRealm {

     @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = "liu"; //用户名及salt1
String salt2 = "0072273a5d87322163795118fdd7c45e";
String password = "be320beca57748ab9632c4121ccac0db"; //加密后的密码
SimpleAuthenticationInfo ai = new SimpleAuthenticationInfo(username, password, getName());
ai.setCredentialsSalt(ByteSource.Util.bytes(username+salt2)); //盐是用户名+随机数
return ai;
}
}

四、密码重试次数限制

如在 1 个小时内密码最多重试 5 次,如果尝试次数超过 5 次就锁定 1 小时,1 小时后可再
次重试,如果还是重试失败,可以锁定如 1 天,以此类推,防止密码被暴力破解。我们通
过继承 HashedCredentialsMatcher,且使用 Ehcache 记录重试次数和超时时间。

 public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

     private Ehcache passwordRetryCache;

     public RetryLimitHashedCredentialsMatcher() {
CacheManager cacheManager = CacheManager.newInstance(CacheManager.class.getClassLoader().getResource("ehcache.xml"));
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
} @Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String)token.getPrincipal();
//retry count + 1
Element element = passwordRetryCache.get(username);
if(element == null) {
element = new Element(username , new AtomicInteger(0));
passwordRetryCache.put(element);
}
AtomicInteger retryCount = (AtomicInteger)element.getObjectValue();
if(retryCount.incrementAndGet() > 5) {
//if retry count > 5 throw
throw new ExcessiveAttemptsException();
} boolean matches = super.doCredentialsMatch(token, info);
if(matches) {
//clear retry count
passwordRetryCache.remove(username);
}
return matches;
}
}
 <?xml version="1.0" encoding="UTF-8"?>
<ehcache name="es"> <diskStore path="java.io.tmpdir"/> <!-- 登录记录缓存 锁定10分钟 -->
<cache name="passwordRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache> </ehcache>

Shiro笔记(四)编码/加密的更多相关文章

  1. 跟开涛老师学shiro -- 编码/加密

    在涉及到密码存储问题上,应该加密/生成密码摘要存储,而不是存储明文密码.比如之前的600w csdn账号泄露对用户可能造成很大损失,因此应加密/生成不可逆的摘要方式存储. 5.1 编码/解码 Shir ...

  2. Java加密与解密笔记(四) 高级应用

    术语列表: CA:证书颁发认证机构(Certificate Authority) PEM:隐私增强邮件(Privacy Enhanced Mail),是OpenSSL使用的一种密钥文件. PKI:公钥 ...

  3. Java加密与解密笔记(二) 对称加密

    前面的仅仅是做了编码或者摘要,下面看看真正的加密技术. DES public class DESUtil { static final String ALGORITHM = "DES&quo ...

  4. [AS3]as3用ByteArray来对SWF文件编码加密实例参考

    [AS3]as3用ByteArray来对SWF文件编码加密实例参考,简单来说,就是将 swf 以 binary 的方式读入,并对 ByteArray 做些改变,再重新存成 swf 档.这个作业当然也可 ...

  5. Java加密与解密笔记(三) 非对称加密

    非对称的特点是加密和解密时使用的是不同的钥匙.密钥分为公钥和私钥,用公钥加密的数据只能用私钥进行解密,反之亦然. 另外,密钥还可以用于数字签名.数字签名跟上文说的消息摘要是一个道理,通过一定方法对数据 ...

  6. Shiro笔记(一)基本概念

    Shiro笔记(一)基本概念 一.简介 Shiro是一个Java安全框架,可以帮助我们完成:认证.授权.加密.会话管理.与Web集成.缓存等. Authentication:身份认证/登录,验证用户是 ...

  7. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

  8. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  9. 《MFC游戏开发》笔记四 键盘响应和鼠标响应:让人物动起来

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9327377 作者:七十一雾央 新浪微博:http:// ...

随机推荐

  1. ES系列一、CentOS7安装ES 6.3.1、集成IK分词器

    Elasticsearch 6.3.1 地址: wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3. ...

  2. VS2017编译boost库

    1.http://www.boost.org/     下载boost库. 2.解压到 D:\ProgramFiles\boost 3.环境配变量配置     VS2017更加注重跨平台性,安装文件较 ...

  3. centos常用网络管理命令

    网卡配置命令:ifconfig (ip addr , ip link) ifconfig:显示所有活动状态的相关信息    ifconfig Interface:仅显示指定接口的相关信息    ifc ...

  4. Spark的HA部署

    一.安装JDK.Scala 二.安装zookeeper 三.安装Hadoop 四.安装Spark 1.修改spark/conf/spark-env.sh export JAVA_HOME=/usr/j ...

  5. POJ 3126 Prime Path (素数+BFS)

    题意:给两个四位素数a和b,求从a变换到b的最少次数,每次变换只能变换一个数字并且变换的过程必须也是素数. 思路:先打表求出四位长度的所有素数,然后利用BFS求解.从a状态入队,然后从个位往千位的顺序 ...

  6. JDK和CGLIB生成动态代理类的区别

     关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代 ...

  7. Codeforces Round #216 (Div. 2)

    以后争取补题不看别人代码,只看思路,今天就是只看思路补完的题,有点小激动. A. Valera and Plates 水题,贪心地先放完第一种食物,在考虑第二种. 居然被卡了一会,心态要蹦 :(: # ...

  8. thinkphp中AJAX返回ajaxReturn()方法分析

    本文分析了thinkphp中AJAX返回ajaxReturn()方法.分享给大家供大家参考,具体如下: 系统支持任何的AJAX类库,Action类提供了ajaxReturn方法用于AJAX调用后返回数 ...

  9. DP-hdu1176

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1176 这道题与动态规划中的数塔问题十分类似,因此如果对于数塔问题还不太明白的,可以先参考一下博客: 数 ...

  10. 《Android进阶之光》--RxJava结合Retrofit访问网络

    1)配置 dependencies{ ... compile 'io.reactivex:rxjava:1.2.0' compile 'io.reactivex:rxandroid:1.2.1' co ...