中國監(jiān)理建設協(xié)會網(wǎng)站今日重大軍事新聞
文章目錄
- 1. 前言
- 2. 密碼加密
1. 前言
本文 主要實現(xiàn) 對密碼進行加密 ,因為 使用 md5 容易被窮舉 (彩虹表) 而破解 ,使用
spring security
框架又太大了 (殺雞用牛刀) 。
?
所以本文 就自己實現(xiàn)一個密碼加密 .
?
2. 密碼加密
?
這里我們通過 加鹽是方式 來 對密碼進行加密 .
加鹽 通常分為兩部分 :
- 鹽值 : 通常使用隨機數(shù)
- 加密數(shù)據(jù)
?
將鹽值與加密數(shù)據(jù)合在一起 就是 加鹽數(shù)據(jù)了 , 加鹽數(shù)據(jù)通常來說是安全的
?
這里我們 鹽值 是 隨機的 每次加鹽的數(shù)字都是不同的,這里通過窮舉 來 破解我們的數(shù)據(jù) 假設破解 一條數(shù)據(jù) 花費的時間 1 天 , 我們 有 1 千w 個數(shù)據(jù), 一個數(shù)據(jù)
是一天 , 那么 1 千 w 個數(shù) , 全部破解 時間是非常多的 .
?
這里成本大于利益 , 那么誰去破解呢 , 所以這樣做 我們的密碼 就是安全的 .
?
知道加鹽 , 下面就來自己實現(xiàn)一個加鹽的方法
- 加密 : 隨機鹽 +
$
+ 最終加密密碼 - 解密 : 先通過 $ 進行分割 , 得到隨機鹽 + 最終密碼 ,然后通過 md5 對 新輸入的密碼 與 得到的隨機鹽 進行加密 , 將得到的 新的加密密碼 和 之前分割得到的 最終密碼 進行對比 如果 相等 那么 就是相同的密碼 返回 true,如果不相等 就是不同的密碼 返回 false
?
代碼實現(xiàn) :
這里我采用 的 是 使用 hutool
中的 MD5 進行 加密 的 所以需要引入 依賴
<!-- 添加 hutool --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency>
?
創(chuàng)建一個 PasswordUtil , 在這個類里面完成我們的加密和 解密 .
package com.example.usermanager.tools;import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import org.springframework.util.StringUtils;import java.util.UUID;/*** 密碼工具類* 1. 加密 (加鹽)* 2. 解密*/public class PasswordUtil {/*** 加密 (加鹽)** @param password* @return*/// 生成的 UUID 帶有 - : UUID.randomUUID();public static String encrypt(String password) {// 生成 uuid 不加 - 的 .// 隨機鹽值String salt = IdUtil.simpleUUID();// 密碼 (隨機鹽值 + 密碼)String finalPassword = SecureUtil.md5(salt + password);return salt + "$" + finalPassword;}/*** 解密** @param password 要驗證的密碼 (未加密)* @return 數(shù)據(jù)庫中的加了鹽值的密碼*/public static boolean decrypt(String password, String securePassword) {boolean result = false;if (StringUtils.hasLength(password) && StringUtils.hasLength(securePassword)) {if (securePassword.length() == 65 && securePassword.contains("$")) {// 注意 : $ 是特殊字符 使用 split 需要轉(zhuǎn)義String[] securePasswordArr = securePassword.split("\\$");// 鹽值String salt = securePasswordArr[0];// 根據(jù)鹽值加密的密碼String finalPassword = securePasswordArr[1];// 使用同樣的加密算法 和 隨機鹽值生成最終的加密的密碼password = SecureUtil.md5(salt + password);// 進行對比if (finalPassword.equals(password)) {result = true;}}}return result;}public static void main(String[] args) {String password = "123456";String dbPassword = PasswordUtil.encrypt(password);System.out.println("加密密碼 " + dbPassword);boolean result = PasswordUtil.decrypt("123456",dbPassword);String password2 = "123456789";boolean result2 = PasswordUtil.decrypt(password2,dbPassword);System.out.println(result);System.out.println(result2);}
}
?
效果 :
?
?
擴展 : 這里我們可以 對 加密密碼 進行一個對稱加密 ,對稱加密后得到一個 32 位 數(shù)據(jù) , 我們的程序可以通過 公鑰 對 32 數(shù)據(jù) 還原 ,然后再通過我們寫的 decrypt 進行 解密 .
?
這里主要是一個小功能, 可以將這個加密 放在我們的項目中 .