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. arch linux 安装指南

    (如果不想折腾arch linux,推荐直接使用 manjaro:  https://manjaro.org/ ) 1.安装准备 Arch Linux 能在任何内存空间不小于 512MB 的 x86_ ...

  2. TCP建立流程 【转】

    解决TCP连接数过多的问题 TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题 TCP状态迁移 大家对netstat -a命令很熟悉,但是,你有没有注意到STATE一栏呢,基 ...

  3. nodejs 使用mysql 进行查询的问题

    因为返回的是个对象 var selectSql1="select * from spc_word_mst where WORD_ID=? limit 0,1 "var select ...

  4. centos7.2环境nginx+mysql+php-fpm+svn配置walle自动化部署系统详解

    centos7.2环境nginx+mysql+php-fpm+svn配置walle自动化部署系统详解 操作系统:centos 7.2 x86_64 安装walle系统服务端 1.以下安装,均在宿主机( ...

  5. Spring MVC注解配置

    http://blog.csdn.net/eventys/article/details/8208808

  6. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  7. npm install 报错(npm ERR! errno -4048,Error: EPERM: operation not permitted,)解决方法

    npm ERR! path E:\SouthernPowerGridProject\web_project\AutoOPS\autoops\node_modules\fsevents\node_mod ...

  8. Jmeter安装和启动和使用

    一.安装配置JDK 1.下载安装jdk,地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.配置JDK环境变 ...

  9. 读取本地图片 BitmapImage

    BitmapImage defImage = new BitmapImage(); defImage.BeginInit(); defImage.UriSource = new Uri(@" ...

  10. Java字符串的操作

    判断字符串是否存在 使用str.contains("values") public class one { /*判断某个字符串是否存在*/ public static void m ...