All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.basics.util.KeyUtil Maven / Gradle / Ivy

package cn.basics.util;

import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Date;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.alibaba.fastjson.JSONObject;

/**
 * @ClassName: KeyUtil
 * @Description: TODO(用户秘钥工具)
 * @author [email protected] (苟志强)
 * @date 2017-5-31 上午11:34:32
 */
@SuppressWarnings("restriction")
public class KeyUtil {
	
	public static void main(String[] args) throws InterruptedException {
		KeyUtil keyUtil = new KeyUtil();
		JSONObject key = keyUtil.getUserKey("test", 0, true, 6);
		System.out.println(key.toJSONString());
		
		Thread.sleep(3000);
		System.out.println(keyUtil.checkUserKey(key.getString("user_priveat_key"), key.getString("user_public_key")).toJSONString());
		
		JSONObject encrypt = keyUtil.encrypt(key.getString("user_priveat_key"), "明文加密");
		System.out.println(encrypt.toJSONString());
		
		Thread.sleep(3000);
		System.out.println(keyUtil.decrypt(key.getString("user_public_key"), encrypt.getString("ciphertext")));
	}
	/**
	 * @Title: getMD5
	 * @Description: TODO(对字符串md5加密)
	 * @author [email protected] (苟志强)
	 * @date  2017-6-6 下午4:20:28
	 * @param str 需要MD5加密的字符串
	 * @throws Exception
	 */
	public static String getMD5(String str) throws Exception {
	    try {
	        // 生成一个MD5加密计算摘要
	        MessageDigest md = MessageDigest.getInstance("MD5");
	        // 计算md5函数
	        md.update(str.getBytes());
	        // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
	        // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
	        return new BigInteger(1, md.digest()).toString(16);
	    } catch (Exception e) {
	        throw new Exception("MD5加密出现错误");
	    }
	}
	/**
	 * 秘钥最大有效时间(单位:分钟)
	 */
	private long key_max_valid_tiem = 60*8+1;//8小时+1分钟
	/**
	 * @Title: encrypt
	 * @Description: TODO(明文加密)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午4:53:38
	 * @param private_key 用户私钥
	 * @param express 明文字符串
	 * @return 加密结果json对象
	 */
	public JSONObject encrypt(String private_key,String express){
		JSONObject json = new JSONObject();
		//获取加密key
		JSONObject json_pk = checkUserPrivateKey(private_key);
		if(json_pk.getLong("state")==10000){
			String key = json_pk.getString("key");
			try {
				String ciphertext = null;
				if(express!=null&&!"".equals(express)){
					express = URLEncoder.encode(express,"utf-8");
					byte[] key_by = key.getBytes("utf-8");
					byte[] ex_by = express.getBytes("utf-8");
					for (int i = 0,j=0,len = ex_by.length; i < len; i++,j++) {
						ex_by[i] += key_by[j];
						if(j >= key_by.length-1){
							j = 0;
						}
					}
					ciphertext = new BASE64Encoder().encode(Arrays.toString(ex_by).getBytes());
				}
				if(ciphertext==null)throw new Exception();

				json.put("state", 10000);
				//				json.put("key", key);
				json.put("state_msg", "加密成功!");
				json.put("ciphertext", ciphertext);
			} catch (Exception e) {
				json.put("state", 10001);
				json.put("state_msg", "对明文进行加密失败,详细:"+e.toString());
			}
		}else{
			json = json_pk;
		}
		return json;
	}
	/**
	 * @Title: decrypt
	 * @Description: TODO(密文解码)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午5:32:36
	 * @param public_key 用户公钥
	 * @param ciphertext 密文字符串
	 * @return 解密结果json对象
	 */
	public JSONObject decrypt(String public_key,String ciphertext){
		JSONObject json = new JSONObject();
		//获取加密key
		JSONObject json_pk = checkUserPublicKey(public_key);
		if(json_pk.getLong("state")==10000){
			String key = json_pk.getString("key");
			try {
				String express = null;  
				if(ciphertext!=null&&!"".equals(ciphertext)){
					BASE64Decoder decoder = new BASE64Decoder();  
					byte[] key_by = key.getBytes("utf-8");
					String ex_str = URLDecoder.decode(new String(decoder.decodeBuffer(ciphertext), "utf-8"),"utf-8");
					if(ex_str.indexOf("[")==0)ex_str=ex_str.substring(1);
					if(ex_str.indexOf("]")==ex_str.length()-1)ex_str=ex_str.substring(0,ex_str.length()-1);
					String[] ex_by_str = ex_str.split(",");
					byte[] ex_by = new byte[ex_by_str.length];
					for (int i = 0,j=0,len = ex_by.length; i < len; i++,j++) {
						ex_by[i] = (byte) (Byte.parseByte(ex_by_str[i].trim()) - key_by[j]);
						if(j >= key_by.length-1){
							j = 0;
						}
					}
					express = new String(ex_by, "utf-8");
					express = URLDecoder.decode(express,"utf-8");
				}
				if(express==null)throw new Exception();
				json.put("state", 10000);
				//				json.put("key", key);
				json.put("state_msg", "解密成功!");
				json.put("express", express);
			} catch (Exception e) {
				json.put("state", 10001);
				json.put("state_msg", "对明文进行解密失败,详细:"+e.toString());
			}
		}else{
			json = json_pk;
		}
		return json;
	}
	/**
	 * @Title: checkUserPrivateKey
	 * @Description: TODO(校验用户私钥)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午3:42:33
	 * @param userId 用户ID
	 * @param private_key 私钥
	 * @return 校验结果json对象
	 */
	public JSONObject checkUserPrivateKey(String private_key){
		JSONObject json = new JSONObject();
		int type = 6;
		try {
			type = Integer.parseInt(private_key.substring(private_key.length()-1));
			switch (private_key.length()) {
			case 32:case 64:new Exception();
			}
		} catch (Exception e) {
			json.put("state", 20008);
			json.put("state_msg", "用户私钥错误!");
			return json;
		}
		//获取基串
		String keys_string = getketsString(type);
		//获取加密串
		String key = "";
		//获取生成时间戳
		String time_key = private_key.substring(0,13);
		key = private_key.substring(25);//排除时间戳+userId
		String timeString = "";
		for (int i = 0,length=time_key.length(); i < length; i++) {
			timeString += keys_string.indexOf(time_key.substring(i,i+1));
		}
		long time = Long.parseLong(timeString);
		//获取有效时间
		String validTiem_key = private_key.substring(private_key.length()-4);
		key = key.substring(0,key.length()-4);//排除有效时间+类型
		String validTiemString = "";
		for (int i = 0; i < 3; i++) {
			validTiemString += keys_string.indexOf(validTiem_key.substring(i,i+1));
		}
		long validTiem = Long.parseLong(validTiemString);
		//校验私钥是否过期
		long interval_time = System.currentTimeMillis() - time;
		if(interval_time/1000/60>=validTiem && validTiem != 0){
			json.put("state", 20009);
			json.put("state_msg", "该私钥已经过期!");
		}else{
			json.put("state", 10000);
			json.put("key", key);
			json.put("state_msg", "私钥校验通过!");
		}
		return json;
	}
	/**
	 * @Title: checkUserPublicKey
	 * @Description: TODO(校验公钥)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午3:44:03
	 * @param private_key 私钥
	 * @param public_key 公钥
	 * @return 校验结果json对象
	 */
	public JSONObject checkUserPublicKey(String public_key){
		JSONObject json = new JSONObject();
		int type = 6;
		try {
			type = Integer.parseInt(public_key.substring(public_key.length()-1));
		} catch (Exception e) {
			json.put("state", 20010);
			json.put("state_msg", "用户公钥错误!");
			return json;
		}
		//获取基串
		String keys_string = getketsString(type);
		//获取位移数
		Integer random = keys_string.indexOf(public_key.substring(0,1));
		String public_key_body = "";
		for (int i = 1,length=public_key.length()-1; i < length; i++) {
			int inde = keys_string.indexOf(public_key.substring(i,i+1));
			inde = inde+random>=keys_string.length()?inde+random-keys_string.length()+1:inde+random;
			public_key_body += keys_string.charAt(inde);
		}
		if(!"".equals(public_key_body)){
			json.put("state", 10000);
			json.put("key", public_key_body);
			json.put("state_msg", "公钥校验成功!");
		}else{
			json.put("state", 20011);
			json.put("state_msg", "公钥校验失败!");
		}
		return json;
	}

	/**
	 * @Title: checkUserPublicKey
	 * @Description: TODO(校验私钥/公钥是否匹配)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午3:44:03
	 * @param private_key 私钥
	 * @param public_key 公钥
	 * @return 校验结果json对象
	 */
	public JSONObject checkUserKey(String private_key,String public_key){
		JSONObject json = new JSONObject();
		int type = 6;
		try {
			if(!private_key.substring(private_key.length()-1).equals(public_key.substring(public_key.length()-1))){
				json.put("state", 20005);
				json.put("state_msg", "用户公钥私钥不匹配!");
				return json;
			}
			type = Integer.parseInt(private_key.substring(private_key.length()-1));
			switch (private_key.length()) {
			case 32:case 64:new Exception();
			}
		} catch (Exception e) {
			json.put("state", 20006);
			json.put("state_msg", "用户私钥错误!");
			return json;
		}
		//获取基串
		String keys_string = getketsString(type);
		//获取位移数
		Integer random = keys_string.indexOf(public_key.substring(0,1));
		String public_key_body = "";
		for (int i = 1,length=public_key.length()-1; i < length; i++) {
			int inde = keys_string.indexOf(public_key.substring(i,i+1));
			inde = inde+random>=keys_string.length()?inde+random-keys_string.length()+1:inde+random;
			public_key_body += keys_string.charAt(inde);
		}
		if(private_key.indexOf(public_key_body)!=-1){
			JSONObject json_pr = checkUserPrivateKey(private_key);
			JSONObject json_pu = checkUserPublicKey(public_key);
			if("10000".equals(json_pr.getString("state"))){
				if("10000".equals(json_pu.getString("state"))){
					json.put("state", 10000);
					//					json.put("key", public_key_body);
					json.put("state_msg", "公钥私钥匹配成功!");
				}else{
					json = json_pu;
				}
			}else{
				json = json_pr;
			}
		}else{
			json.put("state", 20007);
			json.put("state_msg", "用户公钥私钥不匹配!");
		}
		return json;
	}


	/**
	 * @Title: getUserKey
	 * @Description: TODO(生成用户私钥、公钥)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 上午11:39:21
	 * @param userId 用户ID
	 * @param validTiem 当前时间起有效时间(单位:分钟)
	 * @param is64 true 64位秘钥 false 32位秘钥
	 * @param type 0:数字 1:小写字母 2:小写+数字 3:大写字母 4:大写+数字 5:小写+大写 6:小写+大写+数字 default:数字
	 * @return 用户私钥公钥json对象
	 */
	public JSONObject getUserKey(String userId,long validTiem,boolean is64,int type){
		JSONObject json = new JSONObject();
		//获取秘钥长度
		Integer key_length = is64?64:32;
		if (userId.length()>12) {
			json.put("state", 20001);
			json.put("state_msg", "用户ID超过私钥支持最大长度12!");
			return json;
		}else if(key_max_valid_tiem=validTiem){
			json.put("state", 20003);
			json.put("state_msg", "秘钥有效时间不能小等于0!");
			//			return json;
		}
		try {
			//获取基串
			String keys_string = getketsString(type);
			//获取当前时间字符串
			String timeString = new Date().getTime()+"";
			//获取秘钥前缀
			String key_prefix = "";
			for (int i = 0,length=timeString.length(); i < length; i++) {
				key_prefix += keys_string.charAt(Integer.parseInt(timeString.substring(i,i+1)));
			}
			//有效时间补位 补位后是长度为3的字符串
			String validTiemString = validTiem+"";
			if((validTiem+"").length()<3){
				switch (3-(validTiem+"").length()) {
				case 1:validTiemString="0"+validTiemString;break;
				case 2:validTiemString="00"+validTiemString;break;
				}
			}
			//获取秘钥后缀
			String key_suffix = "";
			for (int i = 0; i < 3; i++) {
				key_suffix += keys_string.charAt(Integer.parseInt(validTiemString.substring(i,i+1)));
			}
			key_suffix += type;
			//获取秘钥user
			String key_user = "";
			for (int i = 0,length = userId.length(); i < length; i++) {
				int inde = keys_string.indexOf(userId.substring(i,i+1));
				inde = inde-1>0?inde-1:keys_string.length()-1;
				key_user += keys_string.charAt(inde);
			}
			if(key_user.length()<12){
				switch (12-key_user.length()) {
				case 1:key_user="&"+key_user;break;
				case 2:key_user="!@"+key_user;break;
				case 3:key_user="%^!"+key_user;break;
				case 4:key_user="(&$!"+key_user;break;
				case 5:key_user="$%^*)"+key_user;break;
				case 6:key_user="!(@*#^"+key_user;break;
				case 7:key_user="~&@($#&"+key_user;break;
				case 8:key_user="~)@(#&$@"+key_user;break;
				case 9:key_user="*&^$#&*!@"+key_user;break;
				case 10:key_user="$%&*()&^$%"+key_user;break;
				case 11:key_user="!@)#$&*&*(@"+key_user;break;
				case 12:key_user="!$^&*#(*@!@#"+key_user;break;
				}
			}
			//获取秘钥body
			String key_body = getRandomString(key_length, type);
			//输出
			String private_ket = key_prefix+key_user+key_body+key_suffix;
			json.put("state", 10000);
			json.put("state_msg", "获取用户“"+userId+"”的私人秘钥成功,秘钥有效时间"+validTiem+"分钟!");
			//			json.put("key", key_body);
			json.put("validTiem", validTiem);
			json.put("user_priveat_key", private_ket);
			String public_key = getUserPublicKeyByPrivateKey(key_body,keys_string,type);
			json.put("user_public_key", public_key);
			if(checkUserKey(private_ket, public_key).getLong("state")!=10000){
				return getUserKey(userId, validTiem, is64, type);
			}
			return json;
		} catch (Exception e) {
			json.put("state", 20004);
			json.put("state_msg", "获取用户“"+userId+"”的私人秘钥失败,详细:"+e.toString());
			return json;
		}
	}
	/**
	 * @Title: getUserPublicKeyByPrivateKey
	 * @Description: TODO(根据用户私钥获取会员公钥)
	 * @author [email protected] (苟志强)
	 * @param key_body 用户私钥 body
	 * @param keys_string 基串
	 * @param type 0:数字 1:小写字母 2:小写+数字 3:大写字母 4:大写+数字 5:小写+大写 6:小写+大写+数字 default:数字
	 * @date  2017-5-31 下午3:16:37
	 */
	private String getUserPublicKeyByPrivateKey(String key_body, String keys_string, int type) {
		Integer random = getRandom(8)+1;//1-9随机位移
		//获取秘钥前缀
		String public_key_prefix = keys_string.substring(random,random+1);
		String public_key_body = "";
		for (int i = 0,length=key_body.length(); i < length; i++) {
			int inde = keys_string.indexOf(key_body.substring(i,i+1));
			inde = inde-random>0?inde-random:keys_string.length()+(inde-random)-1;
			public_key_body += keys_string.charAt(inde);
		}
		return public_key_prefix+public_key_body+type;
	}

	/**
	 * 随机基础字符串
	 */
	private static final String key_n = "0159376428";//数字
	private static final String key_x = "orgeazibuswfhqpcnljmdytvxk";//小写字母
	private static final String key_x_n = "z2dspvr3wxbaq5cm1nkfghj60u789e4lytio";//小写+数字
	private static final String key_d = "RCQYNGELBDXFUSHMWKIVPJTOAZ";//大写字母
	private static final String key_d_n = "YMKHOWX3PINSE579FVTZQR6JLBC0G8AD412U";//大写+数字
	private static final String key_x_d = "zOBoltAWRMZaebQrhmjgPxfvEpwCLNcVFTIHJdkqKuXDyGSUnsiY";//小写+大写
	private static final String key_x_d_n = "OYMxQcz4s8WHw39RtbaUGS0FhVrl1uIJKgfken5pXoZqmi7vdEP6NBLyA2DTjC";//小写+大写+数字
	/**
	 * 基础字符串更新信息
	 */
	//	private long update_time = 0;//更新前旧串
	//	private String new_key_string = "";//新串
	//	private String used_key_string = "";//更新前旧串

	/**
	 * @Title: getRandomString
	 * @Description: TODO(获取指定长度随机字符串)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 上午11:44:25
	 * @param length 字符串长度
	 * @param type 0:数字 1:小写字母 2:小写+数字 3:大写字母 4:大写+数字 5:小写+大写 6:小写+大写+数字 default:数字
	 * @return 返回随机字符串
	 */
	public static String getRandomString(int length,Integer... type){
		String keysString = getketsString(type);
		StringBuffer sb = new StringBuffer();
		for (int i = 0,len = keysString.length(); i < length; i++) {
			sb.append(keysString.charAt(getRandom(len-1)));
		}
		if(sb.length()!=length){
			String rbs = getRandomString(length,type);
			return rbs;
		}
		return sb.toString();
	}
	/**
	 * @Title: getketsString
	 * @Description: TODO(获取基串)
	 * @author [email protected] (苟志强)
	 * @date  2017-5-31 下午3:29:39
	 * @param type 0:数字 1:小写字母 2:小写+数字 3:大写字母 4:大写+数字 5:小写+大写 6:小写+大写+数字 default:数字
	 * @return 根据类型返回基串
	 */
	private static String getketsString(Integer... type) {
		String keysString;
		switch (type.length>0?type[0]:-1) {
		case 0:keysString = key_n;break;
		case 1:keysString = key_x;break;
		case 2:keysString = key_x_n;break;
		case 3:keysString = key_d;break;
		case 4:keysString = key_d_n;break;
		case 5:keysString = key_x_d;break;
		case 6:
		default:keysString = key_x_d_n;break;
		}
		return keysString;
	}
	private static int getRandom(int count) {
		return Integer.parseInt(Math.round(Math.random() * (count))+"");
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy