Shiro笔记(四)编码/加密

Shiro笔记(四)编码/加密

一、编码和解码

 1     //base64编码、解码
 2     @Test
 3     public void testBase64(){
 4         String str="tang";
 5         byte[] encode = Base64.encode(str.getBytes());
 6         System.out.println("Encode result:"+encode);
 7         System.out.println("The decode result:"+Base64.decodeToString(encode));
 8     }
 9 
10     //16进制字符串编码,解码
11     @Test
12     public void testHex(){
13         String str="Java";
14         char[] encode = Hex.encode(str.getBytes());
15         System.out.println("encode result:"+encode);
16         System.out.println("decode result:"+new String(Hex.decode(encode)));
17     }

二、散列算法

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

 1     //MD5算法
 2     @Test
 3     public void testMD5(){
 4         String str="king";
 5         String salt="salt1";
 6         String s = new Md5Hash(str, salt).toString();
 7         System.out.println("MD5 code: "+s);
 8     }
 9 
10     //SHA算法
11     @Test
12     public void testSHA(){
13         String str="king";
14         String salt="salt1";
15         String s = new Sha256Hash(str, salt).toString();
16         System.out.println("SHA code: "+s);
17     }

三、PasswordService/CredentialMatcher

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

 1 public interface PasswordService {
 2 
 3     //输入明文密码得到密文密码
 4     String encryptPassword(Object plaintextPassword) throws IllegalArgumentException;
 5 
 6     /**
 7      * @param submittedPlaintext a raw/plaintext password submitted by an end user/Subject.
 8      * @param encrypted          the previously encrypted password known to be associated with an account.
 9      *                           This value is expected to have been previously generated from the
10      *                           {@link #encryptPassword(Object) encryptPassword} method (typically
11      *                           when the account is created or the account's password is reset).
12      * @return {@code true} if the {@code submittedPlaintext} password matches the existing {@code saved} password,
13      *         {@code false} otherwise.
14      * @see ByteSource.Util#isCompatible(Object)
15      */
16     boolean passwordsMatch(Object submittedPlaintext, String encrypted);
17 }
1 public interface CredentialsMatcher {
2 
3     //匹配用户输入的 token 的凭证(未加密)与系统提供的凭证(已加密)
4     boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);
5 
6 }

Shiro 默认提供了 PasswordService 实现 DefaultPasswordServiceCredentialsMatcher 实现
PasswordMatcher HashedCredentialsMatcher(更强大)。

应用实例:

 1 public class MyRealm extends AuthorizingRealm{
 2 
 3     private PasswordService passwordService;
 4 
 5     public void setPasswordService(PasswordService passwordService) {
 6         this.passwordService = passwordService;
 7     }
 8 
 9     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
10         return null;
11     }
12 
13     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
14         return new SimpleAuthenticationInfo("tang",
15                 passwordService.encryptPassword("123456"),getName());
16     }
17 }

HashedCredentialsMatcher应用:

 1 public class MyRealm2 extends AuthorizingRealm {
 2 
 3     @Override
 4     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
 5         return null;
 6     }
 7 
 8     @Override
 9     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
10         String username = "liu"; //用户名及salt1
11         String salt2 = "0072273a5d87322163795118fdd7c45e";
12         String password = "be320beca57748ab9632c4121ccac0db"; //加密后的密码
13         SimpleAuthenticationInfo ai = new SimpleAuthenticationInfo(username, password, getName());
14         ai.setCredentialsSalt(ByteSource.Util.bytes(username+salt2)); //盐是用户名+随机数
15         return ai;
16     }
17 }

四、密码重试次数限制

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

 1 public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
 2 
 3     private Ehcache passwordRetryCache;
 4 
 5     public RetryLimitHashedCredentialsMatcher() {
 6         CacheManager cacheManager = CacheManager.newInstance(CacheManager.class.getClassLoader().getResource("ehcache.xml"));
 7         passwordRetryCache = cacheManager.getCache("passwordRetryCache");
 8     }
 9 
10     @Override
11     public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
12         String username = (String)token.getPrincipal();
13         //retry count + 1
14         Element element = passwordRetryCache.get(username);
15         if(element == null) {
16             element = new Element(username , new AtomicInteger(0));
17             passwordRetryCache.put(element);
18         }
19         AtomicInteger retryCount = (AtomicInteger)element.getObjectValue();
20         if(retryCount.incrementAndGet() > 5) {
21             //if retry count > 5 throw
22             throw new ExcessiveAttemptsException();
23         }
24 
25         boolean matches = super.doCredentialsMatch(token, info);
26         if(matches) {
27             //clear retry count
28             passwordRetryCache.remove(username);
29         }
30         return matches;
31     }
32 }
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <ehcache name="es">
 3 
 4     <diskStore path="java.io.tmpdir"/>
 5 
 6 
 7 
 8     <!-- 登录记录缓存 锁定10分钟 -->
 9     <cache name="passwordRetryCache"
10            maxEntriesLocalHeap="2000"
11            eternal="false"
12            timeToIdleSeconds="3600"
13            timeToLiveSeconds="0"
14            overflowToDisk="false"
15            statistics="true">
16     </cache>
17 
18 </ehcache>

转载于:https://www.cnblogs.com/Shadowplay/p/7677219.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值