簡單的md5加密資料及密碼複雜度校驗
阿新 • • 發佈:2018-11-04
資料庫通常需要對密碼進行加密處理,如果已經使用了明文,則需要進行加密遷移。
1. 明文資料庫
CREATE DATABASE `test` ; USE `test`; insert into `t_a`(`id`,`name`,`password`) values (1,'123','qw1r1re'), (2,'12','qw1r12re'), (3,'3','qw12r12re'), (4,'4','q12r1we'), (5,'2','qw12r12re'), (6,'423','qw12r12re'), (7,'2341','qw12r312re'), (8,'12','qw123r1e'), (9,'431','qw123re'), (10,'123','qwr312re');
2. 目標資料庫
CREATE DATABASE `test_b` ;
USE `test_b`;
DROP TABLE IF EXISTS `t_a`;
CREATE TABLE `t_a` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(16) DEFAULT NULL,
`password` blob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8;
3.對密碼使用md5加密後遷移到目標庫
INSERT INTO test_b.t_a (name,password)
SELECT name,MD5(password) FROM test.t_a;
加密遷移後的效果:
4. java實現的md5加密工具
public class MD5Utils { public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = s.getBytes(); // 獲得MD5摘要演算法的 MessageDigest 物件 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 使用指定的位元組更新摘要 mdInst.update(btInput); // 獲得密文 byte[] md = mdInst.digest(); // 把密文轉換成十六進位制的字串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str).toLowerCase(); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { System.out.println("資料庫加密和java加密結果對比:"); System.out.println("202cb962ac59075b964b07152d234b70".equals(MD5Utils.MD5("123"))); } }
5. 密碼複雜度校驗
5.1 前臺校驗
function checkPasswordFormat() {
var password=document.getElementsByName("user.password").value;
var strongRegex = new RegExp(
"^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g");
if (strongRegex.test(password)) {
return true;
} else {
alert("密碼格式必須同時有大寫字母,小寫字母,數字,除了字母數字下劃線以外的字元,且至少8位!");
return false;
}
}
5.2 後臺校驗
5.2.1 檢查密碼字串是否連續。KeywordUtil.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class KeywordUtils {
private static Map<String, String> keyMap;
/**
* 檢查字串是否連續
* @param password 密碼字串
* @return 不連續返回false 完全連續返回true
*/
public static boolean checkPassword(String password) {
return checkPassword(password, 0);
}
/**
* 檢查字串是否連續
*
* @param password
* 密碼字串
* @param diff
* 字串連續數相差diff個算連續 例:字串長度為15,
* 理論最大連續個數為14,diff為2時,連續13個時為連續字串,連續12個為非連續字串
* @return 不連續返回false 連續返回true
*
*/
public static boolean checkPassword(String password, int diff) {
if (password.length() <= 1) {
return false;
}
int length = password.length() - 1;
int count = checkContinue(password);
if (count < length - diff) {
return false;
}
return true;
}
private static int checkContinue(String password) {
if (keyMap == null) {
initKeyMap();
}
int count = 0;
for (int i = 0; i < password.length() - 1; i++) {
char c = password.charAt(i);
char nextChar = password.charAt(i + 1);
String s = keyMap.get(c + "");
if (StringUtils.isNotBlank(s) && s.indexOf(nextChar) >= 0) {
count++;
}
}
return count;
}
private static void initKeyMap() {
keyMap = new HashMap<String, String>();
keyMap.put("`", "1!");
keyMap.put("~", keyMap.get("`"));
keyMap.put("1", "`[email protected]");
keyMap.put("!", keyMap.get("1"));
keyMap.put("2", "1qw3!QW#");
keyMap.put("@", keyMap.get("2"));
keyMap.put("3", "[email protected]$");
keyMap.put("#", keyMap.get("3"));
keyMap.put("4", "3er5#ER%");
keyMap.put("$", keyMap.get("4"));
keyMap.put("5", "4rt6$RT^");
keyMap.put("%", keyMap.get("5"));
keyMap.put("6", "5ty7%TY&");
keyMap.put("^", keyMap.get("6"));
keyMap.put("7", "6yu8^YU*");
keyMap.put("&", keyMap.get("7"));
keyMap.put("8", "7ui9&UI(");
keyMap.put("*", keyMap.get("8"));
keyMap.put("9", "8io0*IO)");
keyMap.put("(", keyMap.get("9"));
keyMap.put("0", "9op-(OP_");
keyMap.put(")", keyMap.get("0"));
keyMap.put("-", "0p[=)P{+");
keyMap.put("_", keyMap.get("-"));
keyMap.put("=", "-[]_{}");
keyMap.put("+", keyMap.get("="));
keyMap.put("q", "[email protected]");
keyMap.put("Q", keyMap.get("q"));
keyMap.put("w", "[email protected]#");
keyMap.put("W", keyMap.get("w"));
keyMap.put("e", "3wsdr4#WSDR$");
keyMap.put("E", keyMap.get("e"));
keyMap.put("r", "4edft5$EDFT%");
keyMap.put("R", keyMap.get("r"));
keyMap.put("t", "5rfgy6%RFGY^");
keyMap.put("T", keyMap.get("t"));
keyMap.put("y", "6tghu7^TGHU&");
keyMap.put("Y", keyMap.get("y"));
keyMap.put("u", "7yhji8&YHJI*");
keyMap.put("U", keyMap.get("u"));
keyMap.put("i", "8ujko9*UJKO(");
keyMap.put("I", keyMap.get("i"));
keyMap.put("o", "9iklp0(IKLP)");
keyMap.put("O", keyMap.get("o"));
keyMap.put("p", "0ol;[-)OL:{_");
keyMap.put("P", keyMap.get("p"));
keyMap.put("[", "-p;']=_P:\"}+");
keyMap.put("{", keyMap.get("["));
keyMap.put("]", "=['\\+{\"|");
keyMap.put("}", keyMap.get("]"));
keyMap.put("\\", "]}");
keyMap.put("|", keyMap.get("\\"));
keyMap.put("a", "qwszQWSZ");
keyMap.put("A", keyMap.get("a"));
keyMap.put("s", "wazxdeWAZXDE");
keyMap.put("S", keyMap.get("s"));
keyMap.put("d", "esxcfrESXCFR");
keyMap.put("D", keyMap.get("d"));
keyMap.put("f", "rdcvgtRDCVGT");
keyMap.put("F", keyMap.get("f"));
keyMap.put("g", "tfvbhyTFVBHY");
keyMap.put("G", keyMap.get("g"));
keyMap.put("h", "ygbnjuYGBNJU");
keyMap.put("H", keyMap.get("h"));
keyMap.put("j", "uhnmkiUHNMKI");
keyMap.put("J", keyMap.get("j"));
keyMap.put("k", "ijm,loIJM<LO");
keyMap.put("K", keyMap.get("k"));
keyMap.put("l", "ok,.;pOK<>:P");
keyMap.put("L", keyMap.get("l"));
keyMap.put(";", "pl./'[PL>?\"{");
keyMap.put(":", keyMap.get(";"));
keyMap.put("'", "][;/}{:?");
keyMap.put("\"", keyMap.get("'"));
keyMap.put("z", "asxASX");
keyMap.put("Z", keyMap.get("z"));
keyMap.put("x", "zsdcZSDC");
keyMap.put("X", keyMap.get("x"));
keyMap.put("c", "xdfvXDFV");
keyMap.put("C", keyMap.get("c"));
keyMap.put("v", "cfgbCFGB");
keyMap.put("V", keyMap.get("v"));
keyMap.put("b", "vghnVGHN");
keyMap.put("B", keyMap.get("b"));
keyMap.put("n", "bhjmBHJM");
keyMap.put("N", keyMap.get("n"));
keyMap.put("m", "njk,NJK<");
keyMap.put("M", keyMap.get("m"));
keyMap.put(",", "mkl.MKL>");
keyMap.put("<", keyMap.get(","));
keyMap.put(".", ",l;/<L:?");
keyMap.put(">", keyMap.get("."));
keyMap.put("/", ".;'>:\"");
keyMap.put("?", keyMap.get("/"));
}
}
5.2.2 密碼不包含使用者名稱等。PasswordUtil.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
public class PasswordUtils {
private static Map<String, String> likeMap;
private static final int LONIN_NAME_LENGTH = 4;
public static boolean checkPasswordFormat(String password) {
String pattern = "^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$*";
boolean flag = Pattern.matches(pattern, password);
return !flag;
}
/**
* 檢查密碼是否包含完整使用者名稱、大小寫、形似
*
* @param password密碼
* @param loginName 使用者名稱
* @return 不包含 返回false 包含及形似返回true
*/
public static boolean checkPasswordLoginName(String password,
String loginName) {
if (password.toLowerCase().indexOf(loginName.toLowerCase()) >= 0) {
// 大小寫全匹配
return true;
}
if (likeMap == null) {
initLikeMap();
}
if (loginName.length() > LONIN_NAME_LENGTH) {
return checkLike(password.toLowerCase(), loginName.toLowerCase());
}
return false;
}
private static boolean checkLike(String password, String loginName) {
Integer[][] allData = new Integer[loginName.length()][];
int length = loginName.length();
for (int i = 0; i < loginName.length(); i++) {
char c = loginName.charAt(i);
String s = String.valueOf(c);
List<Integer> list = statCharInString(s, s, password);
Integer[] tmp = new Integer[list.size()];
allData[i] = list.toArray(tmp);
}
List<List<Integer>> returnData = new ArrayList<List<Integer>>();
getData(allData, 0, new ArrayList<Integer>(), returnData);
for (int i = 0; i < returnData.size(); i++) {
List<Integer> data = returnData.get(i);
int totalLength = length - 1;
int value = 0;
int thisLength = totalLength;
int lastValue = -2;
int diffValue = 0;
for (int j = 0; j < data.size(); j++) {
if (data.get(j) == -1) {
thisLength--;
continue;
}
if (lastValue == -2) {
lastValue = data.get(j);
continue;
}
if (data.get(j) - lastValue == 1) {
diffValue++;
}
if (data.get(j) > lastValue) {
value += data.get(j) - lastValue;
} else {
value += lastValue - data.get(j);
}
lastValue = data.get(j);
}
if (totalLength - thisLength > totalLength / 3) {
// 缺少超過3分之一 為不相似
continue;
}
if (diffValue > totalLength * 4 / 5) {
// 連續個數超過 5分之4 為相似
return true;
}
if (value > thisLength - 2 && value < thisLength + 2) {
// 所有數位置差 在範圍+-2內 為相似
return true;
}
}
return false;
}
private static void getData(Integer[][] data, int count,
List<Integer> dataList, List<List<Integer>> allData) {
if (data[count].length == 0) {
List<Integer> tmp = new ArrayList<Integer>();
for (int j = 0; j < dataList.size(); j++) {
tmp.add(dataList.get(j));
}
tmp.add(-1);
if (count < data.length - 1) {
getData(data, count + 1, tmp, allData);
} else {
allData.add(tmp);
}
} else {
for (int i = 0; i < data[count].length; i++) {
List<Integer> tmp = new ArrayList<Integer>();
for (int j = 0; j < dataList.size(); j++) {
tmp.add(dataList.get(j));
}
tmp.add(data[count][i]);
if (count < data.length - 1) {
getData(data, count + 1, tmp, allData);
} else {
allData.add(tmp);
}
}
}
}
private static List<Integer> statCharInString(String oldstr, String s,
String pwd) {
List<Integer> list = new ArrayList<Integer>();
String tmp = new String(pwd);
int length = 0;
while (tmp.indexOf(s) >= 0) {
int index = tmp.indexOf(s);
int l = length + index;
list.add(l);
tmp = tmp.substring(tmp.indexOf(s) + 1);
length += index + 1;
}
if (oldstr.equals(s)) {
String value = likeMap.get(s);
if (value != null) {
list.addAll(statCharInString(oldstr, value, pwd));
}
}
return list;
}
private static void initLikeMap() {
likeMap = new HashMap<String, String>();
likeMap.put("a", "@");
likeMap.put("o", "0");
likeMap.put("1", "l");
likeMap.put("0", "o");
likeMap.put("l", "1");
}
}