`
liulanggoood
  • 浏览: 7664 次
社区版块
存档分类
最新评论

弱口令验证方案设计

阅读更多

1.1    弱口令设计思路

1.1.1    基本校验

弱口令的基本校验包括:口令字符串长度校验、口令字符串包含的字符类型校验、口令字符串包含的不同字符数校验。

口令字符串长度校验:验证口令字符串的长度不能低于规定值(如6)。

口令字符串包含的字符类型校验:把字符类型分为大写字母、小写字母、数组、特殊字符四类,校验口令字符串包含的字符类型不能低于规定值(如2)。

口令字符串包含的不同字符数校验:不区分大、小写时aA算同一字符,区分大、小写时aA为不同字符。校验口令字符串中包含的不同字符数不能低于规定值(如4)。

1.1.2    高级校验

弱口令的高级校验包括:连续字符校验、键盘输入规则校验、弱口令字典校验。

连续字符校验:校验口令字符串中连续字符组成的子串长度不但能高于规定的值(如40%)。

键盘输入规则校验:详细见2.1.3

弱口令字典校验:在弱口令字典中校验该口令字符串是否为弱口令。

1.1.3    键盘输入规则校验

结合笔记本电脑和台式电脑键盘的布局规则,将字符输入键映射为4*10的二维数组矩阵(1-0q-pa-;,z-?),把密码字符串中每各字符格式化为键盘矩阵中对应的坐标,判断连续字符的坐标是否相邻,并记录连续相邻的串长度进行安全性评估

1.2    我的弱口令校验工具

1.2.1  详细验证步骤说明

1:判断密码是否为null或空,如果不是进入下一步,否则返回结果(密码安全性不符合)

2:判断密码字符串长度是否符合要求,默认是大于等于6位,如果是进入下一步,否则返回结果(密码安全性不符合)

3:循环取出密码串中从0位置到长度下限++的子串,进行下面48的操作并记录结果到一个double[]

4:评估密码中包含的字符类型是否符合要求,如果低于下限返回0,否则返回6-10double

5:评估密码至少包含的不同字符数(不区分大、小写),返回int,如果字符数小于下限返回0,否则返回6-10double

6:评估密码字符串是否包含a-z,z-a这样的连续字符,返回一个double,如果连续字符占整个串长度的40%以上返回0,否则返回(1-连续字符占整个串长度的百分比) * 10

7:评估密码字符串是否匹配键盘输入习惯,返回0-10的整数,值越大表示越不符合键盘输入习惯

8:根据3456的评估结果综合评估出密码的安全评估值(0-10double

9:循环3double[]的值,如果全是0返回0,否则从第一个不是0的位置开始累加,如果后一个位置为0则加长度修正值1,如果累加结果大于10,循环结束返回10

10:判断7产生的安全评估值是否大于安全评估值的下限(默认7),是返回true,否则返回false

1.2.2  Java实现类

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

/**
 * <strong>Title : CheckPWD</strong><br>
 * <strong>Description : 密码强度验证</strong><br>
 * <strong>Create on : Dec 6, 2011 7:34:45 PM</strong><br>
 * @author liulang@mochasoft.com.cn<br>
 * @version v1.0<br>
 * <br>
 * 详细验证步骤说明:<br>
 * 1:判断密码是否为null或空,如果不是进入下一步,否则返回结果(密码安全性不符合)<br>
 * 2:判断密码字符串长度是否符合要求,默认是大于等于6位,如果是进入下一步,否则返回结果(密码安全性不符合)<br>
 * 3:循环取出密码串中从0位置到长度下限++的子串,进行下面4到8的操作并记录结果到一个double[]中
 * 4:评估密码中包含的字符类型是否符合要求,如果低于下限返回0,否则返回6-10的double<br>
 * 5:评估密码至少包含的不同字符数(不区分大、小写),返回int,如果字符数小于下限返回0,否则返回6-10的double<br>
 * 6:评估密码字符串是否包含a-z,z-a这样的连续字符,返回一个double,如果连续字符占整个串长度的40%以上返回0,否则返回(1-连续字符占整个串长度的百分比) * 10<br>
 * 7:评估密码字符串是否匹配键盘输入习惯,返回0-10的整数,值越大表示越不符合键盘输入习惯<br>
 * 8:根据3、4、5、6的评估结果综合评估出密码的安全评估值(0-10的double)<br>
 * 9:循环3中double[]的值,如果全是0返回0,否则从第一个不是0的位置开始累加,如果后一个位置为0则加长度修正值1,如果累加结果大于10,循环结束返回10<br>
 * 9:判断7产生的安全评估值是否大于安全评估值的下限(默认7),是返回true,否则返回false
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人-------------修改日期-------------修改描述<br>
 * --------------------------------------------<br>
 * liulang-----------2011/12/7---------<br>
 * &nbsp;&nbsp;1:增加容错处理;<br>
 * &nbsp;&nbsp;2:修改键盘输入习惯匹配评估算法的逻辑;<br>
 * &nbsp;&nbsp;3:增加一个更加严格的键盘习惯匹配算法maches2(可匹配类似1z2x3c4v5b这样的特殊字符串)<br>
 * <br>
 */
public final class CheckPWD {
	private static Logger logger = Logger.getLogger(CheckPWD.class);
	
	/**
	 * 安全密码评估值的下限,取值范围:0-10,默认:7
	 */
	public static double PASSWORD_STRONG = 7;
	
	/**
	 * 密码字符串包含的字符类型(a-z,A-Z,0-9,特殊字符)在密码安全性评估中所占比例,默认:0.15
	 */
	public static double CHAR_TYPE_NUM_THRESHOLD = 0.15;
	
	/**
	 * 密码字符串包含的不同字符数(不区分大、小写,同一键位的视为同一字符)在密码安全性评估中所占比例,默认:0.35
	 */
	public static double MIN_CONTAIN_CHAR_NUM_THRESHOLD = 0.35;
	
	/**
	 * 密码字符串匹配键盘输入习惯在密码安全性评估中所占比例,默认:0.3
	 */
	public static double KEYSET_MATCHER_THRESHOLD = 0.3;
	
	/**
	 * 评估密码字符串中a-z,z-a这样的连续字符在密码安全性评估中所占比例,默认:0.2
	 */
	public static double SEQUENTIAL_CHARS_THRESHOLD = 0.2;
	
	/**
	 * 键盘输入习惯匹配规则严格模式
	 */
	public static int KEYSET_MATCHER_STRICT_MODE = 1;
	
	/**
	 * 键盘输入习惯匹配规则不严格模式
	 */
	public static int KEYSET_MATCHER_UNDEMANDING_MODE = 0;
	
	/**
	 * 密码最小长度,默认为6
	 */
	private static int MIN_LENGTH = 6;
	
	/**
	 * 密码至少包含的不同字符数(不区分大、小写),(例如:"aaa"包含一个字符,"aba"包含2个字符,"aA"包含1个字符等),默认为4
	 */
	private static int MIN_CONTAIN_CHAR_NUM = 4;
	
	/**
	 * 密码至少包含的字符类型数(a-z,A-Z,0-9,特殊字符),默认为2
	 */
	private static int MIN_CHAR_TYPE_NUM = 2;
	
	/**
	 * 中等强度密码键盘规则匹配严格度,默认0.6
	 */
	private static double THRESHOLD_MEDIUM = 0.6;
	
	/**
	 * 高安全度密码键盘规则匹配严格度,默认0.4
	 */
	private static double THRESHOLD_STRONG = 0.4;
	
	/**
	 * 高安全度密码键盘规则匹配严格度,默认0.4
	 */
	private static double MAX_SEQUENTIAL_CHARS_THRESHOLD = 0.4;
	
	/**
	 * 字母顺序A-Z
	 */
	private static String A_Z = "abcdefghijklmnopqrstuvwxyz";
	
	/**
	 * 字母顺序Z-A
	 */
	private static String Z_A = "zyxwvutsrqponmlkjihgfedcba";
	
	/**
	 * shift键产生的字符与非shift键时对应的字符
	 */
	private static Map CONVERSION_MAP =  new HashMap();
	
	/**
	 * 将键盘按键格式话为4*10的矩阵的坐标
	 */
	private static Map DICTIONARY_MAP = new HashMap();
	private static String[] dictionary1 = "1 2 3 4 5 6 7 8 9 0".split("\\s+");
	private static String[] dictionary2 = "q w e r t y u i o p".split("\\s+");
	private static String[] dictionary3 = "a s d f g h j k l ;".split("\\s+");
	private static String[] dictionary4 = "z x c v b n m , . /".split("\\s+");
	private static String[][] DICTIONARY_MATRIX = {dictionary1, dictionary2, dictionary3, dictionary4};
	
	static {	
		CONVERSION_MAP.put("!", "1");
		CONVERSION_MAP.put("@", "2");
		CONVERSION_MAP.put("#", "3");
		CONVERSION_MAP.put("$", "4");
		CONVERSION_MAP.put("%", "5");
		CONVERSION_MAP.put("^", "6");
		CONVERSION_MAP.put("&", "7");
		CONVERSION_MAP.put("*", "8");
		CONVERSION_MAP.put("(", "9");
		CONVERSION_MAP.put(")", "0");
		CONVERSION_MAP.put(":", ";");
		CONVERSION_MAP.put("<", ",");
		CONVERSION_MAP.put(">", ".");
		CONVERSION_MAP.put("?", "/");
		
		for(int i=0, ln=DICTIONARY_MATRIX.length; i<ln; i++) {
			String[] dic = DICTIONARY_MATRIX[i];
			for(int j=0, lnt=dic.length; j<lnt; j++) {
				int[] row_cell = {i,j};
				DICTIONARY_MAP.put(dic[j], row_cell);
			}
		}
	}
	
	private CheckPWD(){
		
	}
	
	/**
	 * 严格的键盘输入习惯匹配规则,匹配连续或者非连续的(可以匹配:1a2s3d4f5g这样的有规律的串),比matches方法的匹配规则更严格
	 * @param matcherList
	 * @param row_cellList
	 * @param index
	 */
	private static void maches2(List matcherList, List row_cellList, int index) {
		for(; index<row_cellList.size(); index++) {
			int[] row_cell_t = (int[]) row_cellList.get(index);
			if(row_cell_t != null) {
				boolean flag = true;
				for(int i=0; i<matcherList.size(); i++) {
					List list = (List) matcherList.get(i);
					for(int j=0; j<list.size(); j++) {
						int[] row_cell = (int[]) list.get(j);
						if(((Math.abs(row_cell_t[0] - row_cell[0]) <= 1) && (Math.abs(row_cell_t[1] - row_cell[1]) <= 1))) {
							list.add(row_cell_t);
							flag = false;
							break;
						}
					}
					if(!flag) break;
				}
				if(flag) {
					List arrt = new ArrayList();
					arrt.add(row_cell_t);
					matcherList.add(arrt);
				}
			}
		}
	}
	
	/**
	 * 键盘输入习惯匹配规则,匹配连续输入(不能匹配:1a2s3d4f5g这样的有规律的串),比maches2方法的匹配规则宽松
	 * @param matcherList
	 * @param row_cellList
	 * @param index
	 */
	private static void matches(List matcherList, List row_cellList, int index) {
		for(int i=0; i<matcherList.size(); i++) {
			List list = (List) matcherList.get(i);
			for(int ln=row_cellList.size(); index<ln; index++) {
				int[] row_cell = (int[]) list.get(list.size()-1);
				int[] row_cell_t = (int[]) row_cellList.get(index);
				//如果相邻的键盘字符(某一个键的左右、上下、斜向相邻)被连续输入,在原匹配链条上增加新的输入
				if((row_cell != null) && (row_cell_t != null) && 
						((Math.abs(row_cell_t[0] - row_cell[0]) <= 1) && (Math.abs(row_cell_t[1] - row_cell[1]) <= 1))) {
					list.add(row_cell_t);
				}else {	//如果新字符和上一匹配链条的结尾字符距离较远,这结束上一匹配链条,以该字符为首增加新的匹配链条
					List arrt = new ArrayList();
					arrt.add(row_cell_t);
					matcherList.add(arrt);
					index++;
					break;
				}
			}
		}
	}
	
	/**
	 * 键盘规则匹配器,返回double
	 * @param password  密码字符串
	 * @return
	 */
	public static double keysetMatcher(String password, int matchesMode) { 
		String t_password = new String(password);
		t_password = t_password.toLowerCase();
		t_password = canonicalizeWord(password);
		logger.debug("****************将密码字符串转换为键盘矩阵的对应坐标 start******************");
		char[] pwdCharArr = t_password.toCharArray();
		List row_cellList = new ArrayList();
		int Num = 0;
		int startIndex = -1;
		for(int i=0, ln= pwdCharArr.length; i<ln; i++) {
			int[] row_cell = (int[]) DICTIONARY_MAP.get(String.valueOf(pwdCharArr[i]));
			if(row_cell != null)  {
				row_cellList.add(row_cell); 
				Num++;
				if(startIndex == -1) startIndex = i; 
			} else row_cellList.add(null);
		}
		logger.debug("****************将密码字符串转换为键盘矩阵的对应坐标 end******************");
		
		logger.debug("****************初始化匹配链条 start******************");
		int index = startIndex+1;
		int[] row_cell0 = (int[]) row_cellList.get(startIndex);
		List matcherList = new ArrayList();
		List arr0 = new ArrayList();
		arr0.add(row_cell0);
		matcherList.add(arr0);
		logger.debug("****************初始化匹配链条 end******************");
		//根据匹配规则进行匹配
		if(KEYSET_MATCHER_UNDEMANDING_MODE == matchesMode) matches(matcherList, row_cellList, index);	//不严格的匹配模式
		else if(KEYSET_MATCHER_STRICT_MODE == matchesMode) maches2(matcherList, row_cellList, index);	//严格的匹配模式
		
		double rValue = 0;
		for(double threshold = THRESHOLD_STRONG; threshold <= THRESHOLD_MEDIUM; threshold+=0.1) {
			boolean flag = true;
			int nMinimumMeaningfulMatchLength =  (int) (Num * threshold);
			//特殊字符(~ ` - _ = + [ { ] } \ | ' ")所占比率上限
			if(threshold <= ((t_password.length() - Num)*1.0/t_password.length())) flag = false;
			if(flag) {
				for(int i=0; i<matcherList.size(); i++) {
					List list = (List) matcherList.get(i);
					if(list.size() >= nMinimumMeaningfulMatchLength) {
						flag = false;
						return rValue;
					}
				}
			}
			if(flag) {
				if(THRESHOLD_MEDIUM == THRESHOLD_STRONG) rValue = 10;
				else rValue = 6 + 4*(THRESHOLD_MEDIUM-threshold)*1.0/(THRESHOLD_MEDIUM-THRESHOLD_STRONG);
				break;
			}
		}
		return rValue;
	}

	/**
	 * 替换密码中的shift键产生的字符转换为非shift键时对应的字符
	 * @param password	密码字符串
	 * @return	替换后的密码字符串
	 */
	private static String canonicalizeWord(String password) {
		StringBuffer sb = new StringBuffer();
		if(password != null && password.length() > 0) {
			for(int i=0; i<password.length(); i++) {
				String cs = String.valueOf(password.charAt(i));
				if(CONVERSION_MAP.get(cs) != null) sb.append(CONVERSION_MAP.get(cs));
				else sb.append(cs);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 搜索字符str中是否包含有regex指定的正则表达式匹配的子串
	 * @param str 待搜索字符串
	 * @param regex	正则表达式字符串
	 * @return	包含匹配子串返回true,否则返回false
	 */
	private static boolean stringFind(String str, String regex) {
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		if(m.find()) return true;
		return false;
	}
	
	/**
	 * 评估密码中包含的字符类型是否符合要求,如果低于下限返回0,否则返回6 + (字符类型总数 - 下限) * 2
	 * @param password  密码字符串
	 * @param num 密码至少包含的字符类型数(a-z,A-Z,0-9,特殊字符),默认为2
	 * @return 
	 */
	public static double checkCharTypeNum(String password, int num) {
		int typeNum = 0;
		if(stringFind(password, "[a-z]+")) typeNum++;
		if(stringFind(password, "[0-9]+")) typeNum++;
		if(stringFind(password, "[A-Z]+")) typeNum++;
		if(stringFind(password, "\\p{Punct}+")) typeNum++;
		double rValue = 0;
		if(typeNum >= num) {
			if(num == 4) rValue = 10;
			else rValue = 6 + (typeNum - num)*1.0/(4-num) * 4; 
		}
		return rValue;
	}
	
	/**
	 * 评估a-z,z-a这样的连续字符,返回一个double,如果连续字符占整个串长度的40%以上返回0,否则返回(1-连续字符占整个串长度的百分比) * 10
	 * @param password
	 * @return
	 */
	public static double checkSequentialChars(String password) {
		String t_password = new String(password);
		t_password = t_password.toLowerCase();
		double rValue = 0;
		int i = 2;
		int n = t_password.length();
		for(; i<n; i++) {
			boolean flag = true;
			for(int j=0; j+i<n; j++) {
				String str = t_password.substring(j, j+i);
				if((A_Z.indexOf(str) != -1) || (Z_A.indexOf(str) != -1)) {
					flag = false;
					break;
				}
			}
			if(flag) {
				if(i*1.0/n > MAX_SEQUENTIAL_CHARS_THRESHOLD)  rValue = 0;
				else rValue = (1-i*1.0/n) * 10;
				break;
			}
		}
		return rValue;
	}
	
	/**
	 * 评估密码至少包含的不同字符数(不区分大、小写),返回int,如果字符数小于下限返回0,否则返回6 + (包含字符数 - 下限),如果大于10,返回10
	 * @param password 密码字符串
	 * @param num 密码至少包含的字符类型数(a-z,A-Z,0-9,特殊字符),默认为2
	 * @return
	 */
	public static double checkMinContainCharNum(String password, int num) {
		String t_password = new String(password);
//		t_password = t_password.replaceAll("(.)\\1+", "$1");
		t_password = t_password.toLowerCase();
		t_password = canonicalizeWord(password);
		Map map = new HashMap();
		int snum = 0;
		for(int i=0,ln= t_password.length(); i<ln; i++) {
			String cs = String.valueOf(t_password.charAt(i));
			if(map.get(cs) == null) {
				map.put(cs, cs);
				snum++;
			}
		}
		double rValue = 0;
		if(snum >= num) rValue = 6 + (snum - num);
		return (rValue > 10 ? 10 : rValue);
	}
	
	/**
	 * 评估密码强度,根据密码长度,包含的字符类型,包含不同字符数,包含的连续字符,键盘输入习惯综合评估密码强度,返回0-10的double
	 * @param password
	 * @return
	 */
	public static double evalPWD(String password, int matchesMode) {
		if(password == null || "".equals(password.replaceAll("\\s+", ""))) return 0;		//判断密码为null或""
		if(MIN_LENGTH > password.length()) return 0;				//判断密码长度是否符合
		
		double[] val = new double[1000];
		int n = 0;
		for(int i=MIN_LENGTH; i<=password.length(); i++) {
			String t_password = password.substring(0, i);
			//评估密码中包含的字符类型是否符合要求
			double typeNumCheckResult = checkCharTypeNum(t_password,MIN_CHAR_TYPE_NUM);
			//评估密码至少包含的不同字符数(不区分大、小写)
			double minContainCharNumCheckResult = checkMinContainCharNum(t_password, MIN_CONTAIN_CHAR_NUM);
			//评估a-z,z-a这样的连续字符
			double sequentialCharsCheckResult = checkSequentialChars(t_password);
			//评估键盘输入习惯
			double keysetMatcherResult = keysetMatcher(t_password, matchesMode);
			logger.debug("评估密码中包含的字符类型结果:"+typeNumCheckResult);
			logger.debug("评估密码至少包含的不同字符数结果:"+minContainCharNumCheckResult);
			logger.debug("评估a-z,z-a这样的连续字符结果:"+sequentialCharsCheckResult);
			logger.debug("评估键盘输入习惯结果:"+keysetMatcherResult);
			if(typeNumCheckResult == 0 || minContainCharNumCheckResult == 0 || sequentialCharsCheckResult == 0 || keysetMatcherResult == 0) {
				val[n] = 0;
			}else {
				val[n] = typeNumCheckResult*CHAR_TYPE_NUM_THRESHOLD + minContainCharNumCheckResult*MIN_CONTAIN_CHAR_NUM_THRESHOLD + 
					sequentialCharsCheckResult*SEQUENTIAL_CHARS_THRESHOLD + keysetMatcherResult*KEYSET_MATCHER_THRESHOLD;
			}
			n++;
		}
		double rValue = 0;
		boolean flag = false;
		for(int i=0; i<n; i++) {
			if(val[i] != 0) {
				rValue += val[i];
				flag = true;
			}
			if(flag && val[i] == 0) rValue += 1;
			if(rValue >= 10) {
				rValue = 10;
				break;
			}
		}
		return rValue;
		
//		//评估密码中包含的字符类型是否符合要求
//		double typeNumCheckResult = checkCharTypeNum(password,MIN_CHAR_TYPE_NUM);
//		//评估密码至少包含的不同字符数(不区分大、小写)
//		double minContainCharNumCheckResult = checkMinContainCharNum(password, MIN_CONTAIN_CHAR_NUM);
//		//评估a-z,z-a这样的连续字符
//		double sequentialCharsCheckResult = checkSequentialChars(password);
//		//评估键盘输入习惯
//		double keysetMatcherResult = keysetMatcher(password, matchesMode);
//		logger.debug("评估密码中包含的字符类型结果:"+typeNumCheckResult);
//		logger.debug("评估密码至少包含的不同字符数结果:"+minContainCharNumCheckResult);
//		logger.debug("评估a-z,z-a这样的连续字符结果:"+sequentialCharsCheckResult);
//		logger.debug("评估键盘输入习惯结果:"+keysetMatcherResult);
//		if(typeNumCheckResult == 0 || minContainCharNumCheckResult == 0 || sequentialCharsCheckResult == 0 || keysetMatcherResult == 0) {
//			return 0;
//		}else {
//			return typeNumCheckResult*CHAR_TYPE_NUM_THRESHOLD + minContainCharNumCheckResult*MIN_CONTAIN_CHAR_NUM_THRESHOLD + 
//				sequentialCharsCheckResult*SEQUENTIAL_CHARS_THRESHOLD + keysetMatcherResult*KEYSET_MATCHER_THRESHOLD;
//		}
	}
	
	/**
	 * 用严格模式校验密码强度,根据密码评估结果判断密码是否可用,默认评估结果大于7的可用
	 * @param password
	 * @return
	 */
	public static boolean checkPwdInStrictMode(String password) {
		double rValue = evalPWD(password, KEYSET_MATCHER_STRICT_MODE);
		if(rValue >= PASSWORD_STRONG)  return true;
		return false;
	}

	/**
	 * 非严格模式校验密码强度,根据密码评估结果判断密码是否可用,默认评估结果大于7的可用
	 * @param password
	 * @return
	 */
	public static boolean checkPwdIndemandingMode(String password) {
		double rValue = evalPWD(password, KEYSET_MATCHER_UNDEMANDING_MODE);
		if(rValue >= PASSWORD_STRONG)  return true;
		return false;
	}
	
	public static void main(String[] args) {
		String[] sArr = {
				"1a2s3d4f5g6h",
				"zcvjlufw123433546",
				"~]sdfa^9mi|",
				"`%0,uTs85vkj",
				"liulanggood123",
				"PASSword_123",
				"yanghao1234",
				"yanghao123",
				"yanghao1981"
		};
		for(int i=0; i<sArr.length; i++) {
			System.out.println("严格模式下校验"+sArr[i]+"的密码强度:"+evalPWD(sArr[i], KEYSET_MATCHER_STRICT_MODE));
			System.out.println("非格模式下校验"+sArr[i]+"的密码强度:"+evalPWD(sArr[i], KEYSET_MATCHER_UNDEMANDING_MODE));
		}
		
	}
}
 

0
0
分享到:
评论
1 楼 wangkezun 2011-12-26  
吐个槽,再复杂的密码也挡不住网站明文存储。

相关推荐

    基于USB-Key的强口令认证方案设计与分析 (2011年)

    该方案使用USB-Key进行用户口令的验证并存储认证的安全参数,能够有效地保护安全参数不被窃取。认证方案在认证过程中对用户的身份信息进行了保护,使用Hash运算计算认证参数,通过用户端和服务器端之间的认证参数的...

    计算机专业毕设精选-asp.net动态口令认证的网上选课系统的设计与实现(源代码+论文).rar

    本资源提供了一个基于ASP.NET技术的动态口令认证网上选课系统的完整解决方案,包括源代码和详细设计文档(论文)。该系统旨在满足现代高校选课管理的需求,通过引入动态口令认证技术,增强了选课过程的安全性和用户...

    毕业设计-基于Java的两个通用安全模块的设计与实现(源代码+论文)

    本文详细介绍了基于口令的身份认证与文件安全传输两个通用安全模块的设计原理和实现过程,分析了当前口令保存的安全性,提出了运用MD5算法...为了方便系统方案的设计与功能的开发,在方案设计前,根据前面的需求分析。

    MySQL数据库:数据库的安全策略.pptx

    数据库管理和维护;;系统安全策略 数据安全策略 用户安全策略 口令安全策略 审计策略 ;每个数据库都可以设置...安全管理员为数据库定义一个审计策略,在需要审计时,必须决定设计的级别,防止数据库的非法使用。;数据库

    ASP具有动态口令认证机制的网上投票系统的设计(源代码+thesis).zip

    ASP.NET MVC是一种成熟的开发框架,它采用模型-视图-控制器的设计模式,将应用程序的逻辑和界面分离,提供了更好的代码组织和可维护性。我们选择ASP.NET MVC框架是因为它具有良好的可扩展性和灵活性,可以轻松地添加...

    asp.net动态口令认证的网上选课系统的设计与实现(源代码+thesis).zip

    ASP.NET MVC是一种成熟的开发框架,它采用模型-视图-控制器的设计模式,将应用程序的逻辑和界面分离,提供了更好的代码组织和可维护性。我们选择ASP.NET MVC框架是因为它具有良好的可扩展性和灵活性,可以轻松地添加...

    SAML2.0 基础理论

    进行验证最简单方式是使用口令。然而,若每个站点都需要各自的一套口令,用户将有难以控制的大量口令。1998年微软首先尝试通过其Passport network提供该问题的全球解决方案。Passport使得任意Web站点使用用户提交给...

    Oracle DBA workshop1 (中文版)

    提供的口令验证函数:VERIFY_FUNCTION 6-28 将限额分配给用户6-29 小结6-31 练习概览:管理用户6-32 7 管理方案对象 课程目标7-2 什么是方案7-3 访问方案对象7-5 命名数据库对象7-6 指定表中的数据类型7-8 创建和...

    oracle10g课堂练习I(1)

    提供的口令验证函数:VERIFY_FUNCTION 6-27 将限额分配给用户 6-28 小结 6-30 练习概览:管理用户 6-31 7 管理方案对象 课程目标 7-2 什么是方案 7-3 访问方案对象 7-5 命名数据库对象 7-6 指定表中的数据...

    一种适用于NFC移动设备的双向认证安全方案

    然后,采用Hash、AES和口令Key动态更新机制,提出了一种适用于NFC移动设备的双向认证安全方案,并设计了自同步机制。最后,利用GNY逻辑以形式化证明的形式证明了方案的安全性,分析表明该方案能解决伪造、重放攻击、...

    SQL注入攻击与防御(安全技术经典译丛)

     4.8 窃取哈希口令  4.8.1 SQL Server  4.8.2 MySQL  4.8.3 Oracle  4.9 带外通信  4.9.1 E-mail  4.9.2 HTTP/DNS  4.9.3 文件系统  4.10 自动利用SQL注入  4.10.1 Sqlmap  4.10.2 Bobcat  ...

    oracle数据库dba管理手册

    9.2.10 用口令文件进行验证 247 9.2.11 口令保护 247 9.2.12 对象级权限 248 9.2.13 列表权限 251 9.3 限制可用的命令:产品用户环境文件 253 9.4 登录期间的口令安全 253 9.5 口令加密与技巧 253 9.5.1 如何存储...

    SQL注入攻击与防御

    4.8 窃取哈希口令 148 4.8.1 SQL Server 149 4.8.2 MySQL 150 4.8.3 Oracle 151 4.9 带外通信 154 4.9.1 E-mail 154 4.9.2 HTTP/DNS 157 4.9.3 文件系统 158 4.10 自动利用SQL注入 161 4.10.1 Sqlmap 161 4.10.2 ...

    计算机网络安全及防范策略.docx

    应在认真研究的基础上下大气力抓好网络运行质量的设计方案。为解除这个网络系统固有的安全隐患,可采取以下措施。 1、网络分段技术的应用将从源头上杜绝网络的安全隐患问题。因为局域网采用以交换机为中心、以路由器...

    可信的智能卡口令双向认证方案 (2011年)

    提出一种基于智能卡的可信双向认证方案,使用散列函数认证身份,采用远程证明方法验证平台可信性。该方 案支持安全会话密钥协商,支持用户身份匿名及口令自由更换,服务器平台证书可更新。分析表明,该方案可以抵抗针对智...

    《计算机网络安全技术》课程标准.doc

    具有网络安全方面的基本理论和知识,掌握网络安全方案设计、 网络操作系统安全配置、网络管理、网络维护的相关技能,并具备数据库管理、数据安 全等相关知识,熟练使用和配置防火墙、VPN、入侵检测、身份验证、...

    【重磅】最新发布执行的商用密码标准汇总(161份).zip

    公钥基础设施 基于数字证书的可靠电子签名生成及验证技术要求 可鉴别的加密机制 匿名数字签名 第2部分:采用群组公钥的机制 智能密码钥匙应用接口规范 密码设备应用接口规范 实体鉴别 第2部分 采用对称加密算法的...

    物联网安全_实验9 信息保密性、完整性和不可抵赖性的综合应用.doc

    PGP(Pretty Good Privacy)的创始人是美国的Phil Zimmermann(菲利普•齐默曼),他在1991年把 RSA 公钥体系的方便和传统加密体系的高速度结合起来,并且在数字签名和密钥认证管理机制上有巧妙的设计。因此 PGP ...

    oracle10g课堂练习I(2)

    提供的口令验证函数:VERIFY_FUNCTION 6-27 将限额分配给用户 6-28 小结 6-30 练习概览:管理用户 6-31 7 管理方案对象 课程目标 7-2 什么是方案 7-3 访问方案对象 7-5 命名数据库对象 7-6 指定表中的数据...

    oracle10g课堂练习II(2)

    重新创建口令验证文件 4-16 小结 4-18 练习概览:恢复丢失的 TEMPFILE 和重做日志文件 4-19 5 数据库恢复 课程目标 5-2 恢复方法 5-3 用户管理的恢复: RECOVER 命令 5-4 RMAN 恢复: RESTORE 和 RECOVER ...

Global site tag (gtag.js) - Google Analytics