
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