文章目錄
- Shiro憑證匹配器(密碼匹配器)
- 1. 普通加密
- Shiro普通加密(md5)實作
- 1.1 撰寫MD5加密工具類MD5Utils
- 1.2 測驗MD5演算法
- 1.3 在applicationContext-shiro.xml添加憑證匹配器(使用默認匹配器)
- 2. 加鹽加密
- 2.1 測驗加鹽加密(添加一個特殊的字串)
- 2.2 配置自定義的密碼匹配器
- 2.3 在applicationContext-shiro.xml添加自定義的憑證匹配器(自定義密碼匹配)
- 2.4 修改業務,當添加一個用戶的時候進行密碼加鹽加密保存
- 2.5 shiro退出登錄
- 2.5 測驗登錄,登錄成功(資料庫密碼已經加鹽加密)
Shiro憑證匹配器(密碼匹配器)
1. 普通加密
加密:將明文加密成密文保存,常見的用戶密碼保存在資料庫中是需要加密碼保存的(防止出現密碼泄露造成用戶的損失),
在實際專案中,密碼基本上都是密文保存的(加密后保存)
常見加密演算法:
MD5,SHA-512,SHA-256等等(或者疊加使用md5(SHA512))
常見加密解密演算法地址:
http://www.ttmd5.com/list.php

Shiro普通加密(md5)實作
實作步驟:
1)對資料庫密碼進行md5加密
使用mysql的md5函式對密碼進行加密,然后直接修改資料庫的用戶密碼測驗登錄,
2) 在applicationContext-shiro.xml,添加加密認證配置
1.1 撰寫MD5加密工具類MD5Utils
/**MD5加密工具類
* 進行資料加密
* 本專案只用于測驗,用shiro自帶的hash.Md5Hash演算法加密
*/
public class MD5Utils {
//參1 傳入的明文
public static String stringToMD5(String plainText) {
byte[] secretBytes = null;
try {
//對明文的位元組進行摘要加密
secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("沒有找到MD5演算法");
}
//radix引數 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;
}
}
1.2 測驗MD5演算法
/**
* 測驗MD5加密工具類
* 測驗shiro自帶的hash.Md5Hash加密
*/
public class MD5UtilsTest {
//測驗MD5工具類加密
@Test
public void stringToMD5() {
//對123456進行MD5加密
String result = MD5Utils.stringToMD5("123456");
//md5(123456)= e10adc3949ba59abbe56e057f20f883e
System.out.println(result);
}
//測驗shiro自帶的hash.Md5Hash演算法加密,(shiro也集成常用的加密的演算法md5,sha-1)
@Test
public void test02() {
// 對123456加密
Md5Hash md5Hash = new Md5Hash("123456");
System.out.println(md5Hash.toString()); //e10adc3949ba59abbe56e057f20f883e
}
}
1.3 在applicationContext-shiro.xml添加憑證匹配器(使用默認匹配器)
<!-- 配置一個密碼的匹配器 -->
<!-- 123456 是用戶提交過來的密碼明文, 密碼的匹配器,得到密文,與資料庫的密碼 -->
<!--創建憑證匹配器-->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--指定加密演算法-->
<property name="hashAlgorithmName" value="md5"/>
</bean>
<!-- 3.創建Realm(類似dao),在AuthRealm類上就不需要加@Component注解了 -->
<bean id="authRealm" class="com.xgf.web.shiro.AuthRealm">
<!-- 使用自定義匹配器(密碼) -->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
2. 加鹽加密
1)為什么要加鹽(加鹽實作加密的意義)
如果只是單純使用md5或sha1進行加密,容易被人利用"彩虹表"撞庫來破解密碼,導致密碼不安全!這時可以進行加鹽加密來解決,
破解方法:將很多的字串進行呼叫加密演算法,生成對應的很多的密文,然后根據密文倒過來查表(這個表非常的大比如100G,時間雖然久一點,但是能夠破解),得出明文(撞庫更具密文查找明文),2)如何加鹽加密
添加一個特殊字串,別人推導明文的時候,還需要去推導那個特殊的字串,增加推導任務,造成算率不夠導致推導不出來等,
3)shiro加鹽加密步驟
1、撰寫代碼對密碼加鹽加密
2、撰寫自定義憑證匹配器
3、在applicationContext-shiro.xml,添加自定義憑證匹配器
2.1 測驗加鹽加密(添加一個特殊的字串)
MD5UtilsTest
//測驗加鹽加密(添加一個特殊字串)
@Test
public void test03() {
//參1:傳入明文 參2:加鹽(特殊字串)
Md5Hash md5Hash = new Md5Hash("123456","strive_day@163.com");
System.out.println(md5Hash.toString());//2f660a3a69e023b9033c83ef3d418c9b
}
//測驗加另一個鹽(另一個字串)
@Test
public void test04() {
Md5Hash md5Hash = new Md5Hash("123456","study@export.com");//參1 傳入明文 參2鹽
System.out.println(md5Hash.toString());//4154661a85ae8bafac91433e7003f4a2和上面的密文不一樣,因為特殊字串鹽不一樣
}
2.2 配置自定義的密碼匹配器
CustomCredentialsMatcher
/**創建自己的密碼匹配器 - 通過加鹽加密對用戶輸入的明文進行加密然后和資料庫中存盤的密文比較
* 必須指定父類SimpleCredentialsMatcher
*/
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
private Logger l = LoggerFactory.getLogger(this.getClass());
//將密碼加密成密文,但需要使用賬號(這里賬號是郵箱)作鹽
//subject.login(token) 獲取頁面提交的密碼 (比如123456) 通過加鹽加密轉為 -> 密文1
//info 調relam 查詢資料庫中的密碼(資料庫中的密碼存盤就是加密存盤的) -> 密文2
//通過比較密文1(用戶輸入的值)和密文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;//密碼不正確
}
}
}
2.3 在applicationContext-shiro.xml添加自定義的憑證匹配器(自定義密碼匹配)
<!--使用自己定義的匹配器-->
<bean id="credentialsMatcher2" class="com.xgf.web.utils.CustomCredentialsMatcher"></bean>
<!-- 3.創建Realm(類似dao),在AuthRealm類上就不需要加@Component注解了 -->
<bean id="authRealm" class="com.xgf.web.shiro.AuthRealm">
<!-- 使用自定義匹配器(密碼) -->
<property name="credentialsMatcher" ref="credentialsMatcher2"/>
</bean>
2.4 修改業務,當添加一個用戶的時候進行密碼加鹽加密保存
UserServiceImpl
@Override
public void saveUser(User user) {
String uuid= UUID.randomUUID().toString();
user.setUserId(uuid);
//原來保存用戶使用的密碼是明文,現在需要對它進行加密
if(user.getPassword()!=null){//不能對空字串進行加密
//使用shiro自帶的加密Md5Hash
//參1:密碼明文 參2:鹽(按照郵箱設定鹽)
Md5Hash md5Hash = new Md5Hash(user.getPassword(),user.getEmail());
user.setPassword(md5Hash.toString());
}
l.info("save user = " + user);
iUserDao.save(user);
}
2.5 shiro退出登錄
UserController
//使用shiro退出登錄(不再使用前面的普通登錄退出了)
@RequestMapping(path = "/loginOut-shiro", method = {RequestMethod.GET, RequestMethod.POST})
public String loginOutShiro(){
//洗掉session中的用戶資訊
Subject subject = SecurityUtils.getSubject();
//shiro退出登錄
subject.logout();
l.info("loginOut-shiro注銷用戶");
return "redirect:/login-shiro.jsp";
}
將header.jsp的注銷方式改為shiro注銷
<%-- 非加密方式注銷 --%>
<%--<a href="${path}/system/user/loginOut" class="btn btn-default btn-flat">注銷</a>--%>
<%--使用shiro退出 subject.logout(); --%>
<a href="${path}/system/user/loginOut-shiro" class="btn btn-default btn-flat">注銷</a>
2.5 測驗登錄,登錄成功(資料庫密碼已經加鹽加密)



轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/211106.html
標籤:java
上一篇:RSA公鑰指數的選取
