为了框架的安全考虑,不管前端加不加密,后端一定是需要加密的。这里先说一下为什么加密?我个人也在无数个夜晚问自己,加密有必要吗?如果前端传输把密码泄露了或者被拦截了,那我即使在后台加密也不安全啊!那既然这样为什么还要加密呢?个人认为后台加密还是主要是针对数据库的保护。如果数据库被攻克了,黑客拿着数据库的密码,直接去请求登录,这时候如果后台没做加密,这就会出现极大的安全隐患。但是做了加密,即使他拿到数据库的数据也无法登录。下面直接进入正题。
1.配置
首先使用shiro的md5加密要在shiro的配置文件中进行配置。此处的配置是接着上一篇文章配置的。
@Configuration
public class ShiroConfig {
@Bean
public MyShiroRealm myShiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher){
MyShiroRealm myShiroRealm = new MyShiroRealm();
//设置加密方式
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher);
return myShiroRealm;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//指定加密方式
credentialsMatcher.setHashAlgorithmName("MD5");
System.out.println("加密方式:MD5");
//加密次数
credentialsMatcher.setHashIterations(1024);
//此处的设置,true加密用的hex编码,false用的base64编码
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
}
2.配置好后,还要设置还要在自定义realm的doGetAuthenticationInfo方法上盐值
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取用户账号和密码
System.out.println("用户认证");
String username = (String) authenticationToken.getPrincipal();
User user = userService.login(username);
if(user == null){
return null;
}
if (user.getStatus() == 1) { //账户冻结
throw new LockedAccountException();
}
//自定义盐值
ByteSource salt = ByteSource.Util.bytes(user.getUsername());
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user,//安全数据
user.getPassword(),//密码
salt,
getName()
);
return authenticationInfo;
}
3.以上两个步骤做完,加密就完成了。但是加密后的密码怎么获取呢?我更新密码或者创建用户时密码如何加密呢?shiro提供了SimpleHash来进行加密,如下:
//利用shiro的加密来生成密码
@Test
public void pwdTest(){
//加密方式
String hashAlgorithmName = "MD5";
//加密次数
int hashInteractions = 1024;
//盐值
String salt = "lisi";
//原密码
String pwd = "123456";
//将得到的result放到数据库中就行了。
String result = new SimpleHash(hashAlgorithmName, pwd, ByteSource.Util.bytes(salt), hashInteractions).toHex();
System.out.println(result);
}
以上代码需要注意的是生成result的编码方式一定要和配置文件中的编码方式一致,即下图:
上图两个地方要保持一致,不然出报异常java.lang.IllegalArgumentException: Odd number of characters.