普通加密
(1)加密
将明文加密成密文保存,账号保存在数据库中是需要加密码的
(2)加密算法
http://www.ttmd5.com/list.php
(3)实现
》1 对数据库密码进行md5加密
使用mysql的md5函数对密码进行加密,然后直接修改数据库的用户密码
》2 在applicationContext-shiro.xml,添加加密认证配置
MD5Utils.java
public class MD5Utils {
public static String stringToMD5(String plainText) {
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有这个md5算法!");
}
String md5code = new BigInteger(1, secretBytes).toString(16);
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
}
Test
@Test
public void test02() {
Md5Hash md5Hash = new Md5Hash("123");//参1 传入明文
System.out.println(md5Hash.toString());
//202cb962ac59075b964b07152d234b70
}
加密认证配置
applicationContext-shiro.xml
<!--配置一个密码的匹配器-->
<!-- 123 是用户提交过来的, 密码的匹配器 得到密文1,与数据库的密码2-->
<!--创建凭证匹配器-->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--指定加密算法-->
<property name="hashAlgorithmName" value="md5"/>
</bean>
<!--2.2.创建Realm-->
<bean id="authRealm" class="com.hy.web.shiro.AuthRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
加盐加密
- (1)普通加密的缺陷
如果只是单纯使用md5或sha1进行加密,容易被人利用"彩虹表"撞库来破解密码,导致密码不安全!这时可以进行加盐加密来解决。
演示: 加盐 - (2)shiro加盐加密
1)编写代码对密码加盐加密
2)编写自定义凭证匹配器
3)在applicationContext-shiro.xml,添加自定义凭证匹配器
applicationContext-shiro.xml
<!--使用自己定义的匹配器-->
<bean id="credentialsMatcher2" class="com.wzx.web.utils.CustomCredentialsMatcher">
</bean>
<!--2.2.创建Realm-->
<bean id="authRealm" class="com.wzx.web.shiro.AuthRealm">
<property name="credentialsMatcher" ref="credentialsMatcher2"/>
</bean>
MD5Utils.java
加盐加密
public class MD5Utils {
//
public static String stringToMD5(String plainText) {//参1 明文
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());//对明文的字节进行摘要
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有这个md5算法!");
}
//16或者32
String md5code = new BigInteger(1, secretBytes).toString(16);
//补0 一个字节转两位的16进制
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
}
Test
通过添加一个参2的盐值更改加密后的密文实现不同盐值不同密文的加密效果
@Test
public void test03() {
Md5Hash md5Hash = new Md5Hash("123","lw@export.com");//参1 传入明文 参2盐
System.out.println(md5Hash.toString());
//1e99dec7db1120f4604ec224cd90d069
}
@Test
public void test04() {
Md5Hash md5Hash = new Md5Hash("123","lz@export.com");//参1 传入明文 参2盐
System.out.println(md5Hash.toString());
//06ebcfe51319bd9420492f82735e9d99
}
修复添加用户时对密码加盐加密
添加用户时候,需要对用户输入的密码加密、加盐,这样就可以使用添加的用户登陆了。
CustomCredentialsMatcher.java
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
private Logger l = LoggerFactory.getLogger(this.getClass());
//将密码加密成密文,但需要使用账号作盐
//subject.login(token) 表示的页面提交的密码 123 -> 密文1
//info 调relam 表示的是数据中的密码 密文2
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
//token获取账号密码
UsernamePasswordToken t = (UsernamePasswordToken) token;
String email = t.getUsername();
//密码是char[] '1','2','3' => "123" new String(char[])
String pwd1 = new String(t.getPassword());
l.info("doCredentialsMatch pwd1 "+pwd1);
//加密
Md5Hash md5Hash = new Md5Hash(pwd1, email);//参1 传入明文 参2盐
pwd1 = md5Hash.toString();
l.info("doCredentialsMatch pwd1 "+pwd1);
//取数据库的密码 此时不用再加密码,因为它就是密文
String pwd2 = (String) info.getCredentials();
l.info("doCredentialsMatch pwd2 "+pwd2);
if (pwd1.equals(pwd2)) {
return true;//密码正确
} else {
return false;//密码不正确
}
}
}
UserServiceImpl.java
@Override
public void saveUser(User user) {
String uuid= UUID.randomUUID().toString();
user.setUserId(uuid);
//原来保存用户使用的密码是明文,现在需要对它进行加密
if(user.getPassword()!=null){
Md5Hash md5Hash = new Md5Hash(user.getPassword(),user.getEmail());//参1 明文 参2 盐
user.setPassword(md5Hash.toString());
}
l.info("saveUser "+user);
iUserDao.save(user);
}