Shiro-密码的MD5加密

 

1.密码的加密

  在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的。

  著名的加密算法,比如 MD5,SHA1

2.MD5加密

  1). 如何把一个字符串加密为MD5

  2). 使用MD5加密算法后,前台用户输入的字符串如何使用MD5加密,需要做的是将当前的Realm 的credentialsMatcher属性,替换为Md5CredentialsMatcher 由于Md5CredentialsMatcher已经过期了,推荐使用HashedCredentialsMatcher 并设置加密算法即可。

/**
* {@code HashedCredentialsMatcher} implementation that expects the stored {@code AuthenticationInfo} credentials to be
* MD5 hashed.
* <p/>
* <b>Note:</b> <a href="http://en.wikipedia.org/wiki/MD5">MD5</a> and
* <a href="http://en.wikipedia.org/wiki/SHA_hash_functions">SHA-1</a> algorithms are now known to be vulnerable to
* compromise and/or collisions (read the linked pages for more). While most applications are ok with either of these
* two, if your application mandates high security, use the SHA-256 (or higher) hashing algorithms and their
* supporting <code>CredentialsMatcher</code> implementations.</p>
*
* @since 0.9
* @deprecated since 1.1 - use the HashedCredentialsMatcher directly and set its
* {@link HashedCredentialsMatcher#setHashAlgorithmName(String) hashAlgorithmName} property.
*/
public class Md5CredentialsMatcher extends HashedCredentialsMatcher { public Md5CredentialsMatcher() {
super();
setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
}
}

3.使用MD5加密

  1). 修改配置文件的Realm 的默认的credentialsMetcher 为

<bean id="jdbcRealm" class="com.java.shiro.realms.ShiroRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property> <!-- 加密算法的名称 -->
<property name="hashIterations" value="1024"></property> <!-- 配置加密的次数 -->
</bean>
</property>
</bean>

  2). 通过断点可以看到,实际的加密为

  

  3). 通过 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 我们可以得到"123456"经过MD5 加密1024后的字符串;

public static void main(String[] args) {
String hashAlgorithmName = "MD5";
String credentials = "123456";
int hashIterations = 1024;
Object obj = new SimpleHash(hashAlgorithmName, credentials, null, hashIterations);
System.out.println(obj);
}

  将realm中的 明文123456改为fc1709d0a95a6be30bc5926fdb7f22f4

在进行登录测试。

登录成功。

4. 以上的加密还存在问题,如果两个人的密码一样,即存在数据表里中的两个加密后的字符串一样,然而我们希望即使两个人的密码一样,加密后的两个字符串也不一样。即需要用到MD5盐值加密。

  1).修改Realm使用盐值加密 完整的ShiroRealm.java

  

public class ShiroRealm extends AuthenticatingRealm {

    @Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("doGetAuthenticationInfo " + token); // 1. 把AuthenticationToken 转换为UsernamePasswordToken
UsernamePasswordToken up = (UsernamePasswordToken) token;
// 2. 从UsernamePasswordToken 中来获取username
String username = up.getUsername();
// 3. 调用数据库的方法,从数据库中查询username对应的用户记录
System.out.println("从数据库中获取userName :" + username + " 所对应的用户信息.");
// 4. 若用户不存在,则可以抛出 UnknownAccoountException 异常
if ("unknown".equals(username)) {
throw new UnknownAccountException("用户不存在");
}
// 5. 根据用户信息的情况,决定是否需要抛出其他的AuthencationException 异常 假设用户被锁定
if ("monster".equals(username)) {
throw new LockedAccountException("用户被锁定");
}
// 6. 根据用户的情况,来构建AuthenticationInfo 对象并返回,通常使用的是
// SimpleAuthenticationInfo
// 以下信息是从数据库获取的. Object principal = username; // principal 认证的实体信息.
// 可以是username,也可以是数据表对应的用户的实体类对象
// String credentials = "fc1709d0a95a6be30bc5926fdb7f22f4"; // credentials:密码
String credentials = null; // credentials:密码
String realmName = getName();
AuthenticationInfo info = null;/*new SimpleAuthenticationInfo(principal, credentials, realmName);*/ if("admin".equals(username)){
credentials = "038bdaf98f2037b31f1e75b5b4c9b26e";
}else if("user".equals(username)){
credentials = "098d2c478e9c11555ce2823231e02ec1";
} ByteSource credentialsSalt = ByteSource.Util.bytes(username);//这里的参数要给个唯一的;

info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
return info;
} }

  上边的密码我们可用mian方法得到

public static void main(String[] args) {
String hashAlgorithmName = "MD5";
String credentials = "123456";
int hashIterations = 1024;
ByteSource credentialsSalt = ByteSource.Util.bytes("user");
Object obj = new SimpleHash(hashAlgorithmName, credentials, credentialsSalt, hashIterations);
System.out.println(obj);
}

经过测试,登录成功。

  2). 笔记

  • 1. 为什么使用 MD5 盐值加密:

    •   希望即使两个原始密码相同,加密得到的两个字符串也不同。
  • 2. 如何做到:
    •   1). 在 doGetAuthenticationInfo 方法返回值创建 SimpleAuthenticationInfo 对象的时候, 需要使用SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName) 构造器
    •   2). 使用 ByteSource.Util.bytes() 来计算盐值.
    •   3). 盐值需要唯一: 一般使用随机字符串或 user id
    •   4). 使用 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 来计算盐值加密后的密码的值.

最新文章

  1. pageX、clientX、screenX、offsetX、layerX、x
  2. shell编写mysql备份工具
  3. javascript必知必会:面象对象编程
  4. 第一次使用Android Studio时你应该知道的一切配置
  5. Animating graphic objects in Windows Forms.
  6. 爬虫:获取多次跳转后的页面url
  7. JVM内存结构之二--新生代及新生代里的两个Survivor区(下一轮S0与S1交换角色,如此循环往复)、常见调优参数
  8. [iOS翻译]《iOS7 by Tutorials》系列:在Xcode 5里使用单元测试(上)
  9. Dynamo和Bigtable对比
  10. redis tcp-backlog配置
  11. 【日报C在23】堆和栈的深入了解
  12. php-fpm 相关
  13. [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property &#39;source&#39; to &#39;org.eclipse.js
  14. 【译】StackExchange.Redis中文使用文档
  15. C11 constant expressions 常量表达式
  16. linux如何安装java环境
  17. ReactNative环境配置的坑
  18. [matlab] 6.粒子群优化算法
  19. 使用Guava的ComparisonChain实现自定义的排序
  20. css---颜色过渡渐变

热门文章

  1. 转 linux下ClamAV使用
  2. 教孩子学编程 Python
  3. WinForm,在另一个线程中更新Form中的数据(转)
  4. Find minimum number of people to reach to spread a message across all people in twitter
  5. jira7.3.6 windows7下安装、中文及破解
  6. 手把手带你入门神秘的RxJava
  7. [bzoj4345][POI2016]Korale_堆_贪心_线段树_dfs
  8. 计算机视觉/图像处理工具箱推荐(转自cvnote)
  9. Java中常用的设计模式代码与理解
  10. python基础学习(八)