package com.lgx8.right.common;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class EncryptUtil {
/**
* 把一个byte类型的数转换成十六位的ASCII
*
* @param ib
* @return
*/
private static String byte2HEX(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
'b', 'c', 'd', 'e', 'f' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}
/**
* 将source进行SHA1加密
*
* @param source
* @return
*/
public static String toSHA1(String source) {
String newstr = "";
MessageDigest sha;
try {
sha = MessageDigest.getInstance("SHA-1");
sha.update(source.getBytes());
newstr = new String(Base64Util.encode(sha.digest()));
newstr = newstr.trim();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return newstr;
}
/**
* 校验LDAP密码(SSHA)与输入密码是否匹配
* @param ldapPwd
* @param oldPwd
* @return
* @throws NoSuchAlgorithmException
*/
public static boolean verifySSHA(String ldapPwd, String oldPwd)
throws NoSuchAlgorithmException {
// MessageDigest 提供了消息摘要算法,如 MD5 或 SHA,的功能,这里LDAP使用的是SHA-1
MessageDigest md = MessageDigest.getInstance("SHA-1");
// 取出加密字符
if (ldapPwd.startsWith("{SSHA}")) {
ldapPwd = ldapPwd.substring(6);
} else if (ldapPwd.startsWith("{SHA}")) {
ldapPwd = ldapPwd.substring(5);
}
// 解码BASE64
byte[] ldappwbyte = Base64Util.decode(ldapPwd);
byte[] shacode;
byte[] salt;
// 前20位是SHA-1加密段,20位后是最初加密时的随机明文
if (ldappwbyte.length <= 20) {
shacode = ldappwbyte;
salt = new byte[0];
} else {
shacode = new byte[20];
salt = new byte[ldappwbyte.length - 20];
System.arraycopy(ldappwbyte, 0, shacode, 0, 20);
System.arraycopy(ldappwbyte, 20, salt, 0, salt.length);
}
// 把用户输入的密码添加到摘要计算信息
md.update(oldPwd.getBytes());
// 把随机明文添加到摘要计算信息
md.update(salt);
// 按SSHA把当前用户密码进行计算
byte[] inputpwbyte = md.digest();
// 返回校验结果
return MessageDigest.isEqual(shacode, inputpwbyte);
}
/**
* 校验一个MD5字符串和一个明文的字符串是否匹配
*
* @param shaData
* sha加密后的数据
* @param password
* 明文密码数据
* @return
*/
public static boolean verifyMD5(String md5Data, String password) {
// 取出加密字符
String passCode = toMD5(password);
return StrTool.equalsIgnoreCase(md5Data, passCode);
}
/**
* 校验一个SHA字符串和一个明文的字符串是否匹配
*
* @param shaData
* sha加密后的数据
* @param password
* 明文密码数据
* @return
*/
public static boolean verifySHA(String shaData, String password) {
// 取出加密字符
if (shaData.startsWith("{SSHA}")) {
shaData = shaData.substring(6);
} else if (shaData.startsWith("{SHA}")) {
shaData = shaData.substring(5);
} else if (shaData.startsWith("{SHA1}")) {
shaData = shaData.substring(6);
}
String passCode = toSHA1(password);
return StrTool.equals(shaData, passCode);
}
/**
* 将source进行md5加密
*
* @param source
* @return
*/
public static String toMD5(String source) {
String newstr = "";
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bs = md5.digest(source.getBytes());
for (int i = 0; i < bs.length; i++) {
newstr += byte2HEX(bs[i]);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return newstr;
}
/**
* 获取一个用于3DES加密的Key
*
* @param key
* @return
*/
private static SecretKey get3DesKey(String key) {
if (key == null) {
key = "private key";
}
// 生成一个DESede密钥对象
SecretKey theKey = null;
try {
byte[] encryptKey = new byte[25];
byte[] tempKey = key.getBytes();
if (tempKey.length < 24 && tempKey.length > 0) {
int times = 24 / tempKey.length + 1;
encryptKey = new byte[tempKey.length * times];
}
for (int i = 0, j = 0; i < encryptKey.length; i++, j++) {
encryptKey[i] = tempKey[j];
if (j == tempKey.length - 1) {
j = -1;
}
}
// 为上一个密钥指定一个DESede key????? DESSede key
DESedeKeySpec spec = new DESedeKeySpec(encryptKey);
// ??? DESSede keys
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("DESede");
theKey = keyFactory.generateSecret(spec);
} catch (Exception e) {
e.printStackTrace();
}
return theKey;
}
/**
* 用指定的key加密字符串
*
*
* @param strPwd
* @param strKey
* @return
* @throws InvalidKeySpecException
*/
public static String DESEncrypt(String strPwd, String strKey) {
if (strPwd == null || "".equals(strPwd)) {
return "";
}
SecretKey theKey = get3DesKey(strKey);
byte[] ciphertext = null;
String cipherString = "";
try {
Cipher cipher = Cipher.getInstance("Desede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, theKey);
byte[] plaintext = strPwd.getBytes("UTF8");
ciphertext = cipher.doFinal(plaintext);
BASE64Encoder enc = new BASE64Encoder();
cipherString = enc.encode(ciphertext);
} catch (Exception e) {
cipherString = strPwd;
e.printStackTrace();
}
return cipherString;
}
/**
* 用指定的key加密字符串
*
* @param strPwd
* @param strKey
* @return
* @throws InvalidKeySpecException
*/
public static String DESEncrypt(String strPwd, String strKey, String target) {
if (strPwd == null || "".equals(strPwd)) {
return "";
}
SecretKey theKey = get3DesKey(strKey);
byte[] ciphertext = null;
String cipherString = "";
try {
Cipher cipher = Cipher.getInstance("Desede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, theKey);
byte[] plaintext = strPwd.getBytes("UTF8");
ciphertext = cipher.doFinal(plaintext);
BASE64Encoder enc = new BASE64Encoder();
cipherString = enc.encode(ciphertext);
} catch (Exception e) {
cipherString = strPwd;
e.printStackTrace();
}
return cipherString + target;
}
/**
* 用指定的key 加密字符串
*
*
* @param strPwdCode
* @param strKey
* @return
* @throws InvalidKeyException
*/
public static String DESDencrypted(String strPwdCode, String strKey) {
if (strPwdCode == null || "".equals(strPwdCode)) {
return "";
}
SecretKey theKey = get3DesKey(strKey);
String output = "";
try {
Cipher cipher = Cipher.getInstance("Desede/ECB/PKCS5Padding");
BASE64Decoder dec = new BASE64Decoder();
byte[] ciphertext = dec.decodeBuffer(strPwdCode);
cipher.init(Cipher.DECRYPT_MODE, theKey);
byte[] decryptedText = cipher.doFinal(ciphertext);
output = new String(decryptedText, "UTF8");
} catch (Exception e) {
output = strPwdCode;
System.out.println("ttt" + strPwdCode);
}
return output;
}
private static final byte[] keyBytes = { 0x13, 0x29, 0x4F, 0x58, 0x1B,
0x4E, 0x38, 0x2D, 0x25, 0x79, 0x51, 0x5C, 0x68, 0x7A, 0x29, 0x74,
0x33 };
/**
* 获取4个随机索引数
*
* @return int[4]
*/
private static int[] getRandomIndex() {
int[] index = new int[4];
int length = keyBytes.length;
Random random = new Random();
for (int i = 0; i < index.length; i++) {
index[i] = getDiffNum(index[i == 0 ? 0 : i - 1], length, random);
}
return index;
}
/**
* 让获取的随机数与上一个随机数不同
*
* @param lastNum
* 上一次的随机数
* @param length
* 随机数上限
* @param random
* 生成随机数类
* @return int
*/
private static int getDiffNum(int lastNum, int length, Random random) {
int tempInt = random.nextInt(length);
int i = 0;
while (tempInt == lastNum) {
if (i >= 3) {
tempInt = (tempInt == length - 1) ? tempInt - 1 : tempInt + 1;
break;
}
tempInt = random.nextInt(length);
++i;
}
return tempInt;
}
/**
* 将字符加密
*
* @param str
* 原文
* @return String 加密后的密文
*/
public static String strEncrypt(String str) throws Exception {
// 将输入的字符串进行换码处理,以支持中文和特殊字符的加密
str = escape(str);
int[] snIndex = getRandomIndex();
int[] snNum = new int[str.length() + 4];
char[] enChar = str.toCharArray();
String result = "";
String temp = "";
for (int i = 0; i < snIndex.length; i++) {
snNum[i] = snIndex[i];
}
int keyIndex = snIndex[0];
for (int j = 0; j < enChar.length; j++) {
snNum[j + 4] = enChar[j] ^ keyBytes[keyIndex];
}
for (int i = 1; i < snIndex.length; i++) {
keyIndex = snIndex[i];
for (int j = 0; j < snNum.length - 4; j++) {
snNum[j + 4] = snNum[j + 4] ^ keyBytes[keyIndex];
}
}
for (int k = 0; k < snNum.length; k++) {
if (snNum[k] < 16) {
temp = "0" + Integer.toHexString(snNum[k]);
} else {
temp = Integer.toHexString(snNum[k]);
}
result += temp;
}
return result;
}
/**
* 将密文解密
*
* @param str
* 密文
* @return String 返回明文
*/
public static String strDecryption(String str) throws Exception {
int[] indexNum = new int[4];
int[] enNum = new int[str.length() / 2 - 4];
String strPerHex = "(\\p{XDigit}){2}";
Pattern testHex = Pattern.compile(strPerHex);
Matcher mHex = testHex.matcher(str);
int i = 0;
while (mHex.find()) {
if (i < 4) {
indexNum[i] = Integer.valueOf(mHex.group().toString(), 16).intValue();
} else {
enNum[i - 4] = Integer.valueOf(mHex.group().toString(), 16).intValue();
}
++i;
}
for (int j = indexNum.length - 1; j >= 0; j--) {
int keyIndex = indexNum[j];
for (int k = 0; k < enNum.length; k++) {
enNum[k] = enNum[k] ^ keyBytes[keyIndex];
}
}
String result = "";
for (int j = 0; j < enNum.length; j++) {
result += (char) enNum[j];
}
// 将解密的字符串进行反换码处理,将特殊编码格式转换为可识别的字符串
result = unescape(result);
return result;
}
// ===== Begin ========JavaScript escape/unescape 编码的 Java
// 实现=====================
private final static String[] hex = { "00", "01", "02", "03", "04", "05",
"06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B",
"1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26",
"27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31",
"32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C",
"3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47",
"48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52",
"53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D",
"5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68",
"69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73",
"74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E",
"7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
"8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94",
"95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA",
"AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5",
"B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0",
"C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB",
"CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6",
"D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1",
"E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC",
"ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
"F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" };
private final static byte[] val = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F };
/**
* 与Javascript相呼应的解码方法
*
* @param s
* 密文
* @return String 明文
*/
public static String unescape(String s) {
StringBuffer sbuf = new StringBuffer();
int i = 0;
int len = s.length();
while (i < len) {
int ch = s.charAt(i);
if (ch == '+') { // space : map to ' '
sbuf.append(' ');
} else if ('A' <= ch && ch <= 'Z') {
sbuf.append((char) ch);
} else if ('a' <= ch && ch <= 'z') {
sbuf.append((char) ch);
} else if ('0' <= ch && ch <= '9') {
sbuf.append((char) ch);
} else if (ch == '-' || ch == '_' || ch == '.' || ch == '!'
|| ch == '~' || ch == '*' || ch == '\'' || ch == '('
|| ch == ')') {
sbuf.append((char) ch);
} else if (ch == '%') {
int cint = 0;
if ('u' != s.charAt(i + 1)) {
cint = (cint << 4) | val[s.charAt(i + 1)];
cint = (cint << 4) | val[s.charAt(i + 2)];
i += 2;
} else {
cint = (cint << 4) | val[s.charAt(i + 2)];
cint = (cint << 4) | val[s.charAt(i + 3)];
cint = (cint << 4) | val[s.charAt(i + 4)];
cint = (cint << 4) | val[s.charAt(i + 5)];
i += 5;
}
sbuf.append((char) cint);
} else {
sbuf.append((char) ch);
}
i++;
}
return sbuf.toString();
}
/**
* 与Javascript相呼应的编码方法
*
* @param s
* 原文
* @return String 编码后的密文
*/
public static String escape(String s) {
StringBuffer sbuf = new StringBuffer();
int len = s.length();
for (int i = 0; i < len; i++) {
int ch = s.charAt(i);
if (ch == ' ') { // space : map to '+'
sbuf.append('+');
} else if ('A' <= ch && ch <= 'Z') { // 'A'..'Z' : as it was
sbuf.append((char) ch);
} else if ('a' <= ch && ch <= 'z') { // 'a'..'z' : as it was
sbuf.append((char) ch);
} else if ('0' <= ch && ch <= '9') { // '0'..'9' : as it was
sbuf.append((char) ch);
} else if (ch == '-'
|| ch == '_' // unreserved : as it was
|| ch == '.' || ch == '!' || ch == '~' || ch == '*'
|| ch == '\'' || ch == '(' || ch == ')') {
sbuf.append((char) ch);
} else if (ch <= 0x007F) { // other ASCII : map to %XX
sbuf.append('%');
sbuf.append(hex[ch]);
} else { // unicode : map to %uXXXX
sbuf.append('%');
sbuf.append('u');
sbuf.append(hex[(ch >>> 8)]);
sbuf.append(hex[(0x00FF & ch)]);
}
}
return sbuf.toString();
}
// ===== End ========JavaScript escape/unescape 编码的 Java
// 实现=====================
public static String unescapeurl(String src){
if(src == null || "".equals(src.trim())) return "";
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos=0,pos=0;
char ch;
while (lastPos<src.length()){
pos = src.indexOf("%",lastPos);
if (pos == lastPos){
if (src.charAt(pos+1)=='u'){
ch = (char)Integer.parseInt(src.substring(pos+2,pos+6),16);
tmp.append(ch);
lastPos = pos+6;
}else{
ch = (char)Integer.parseInt(src.substring(pos+1,pos+3),16);
tmp.append(ch);
lastPos = pos+3;
}
}else{
if (pos == -1){
tmp.append(src.substring(lastPos));
lastPos=src.length();
}else{
tmp.append(src.substring(lastPos,pos));
lastPos=pos;
}
}
}
return tmp.toString();
}
public static void main(String[] args) {
System.out.println(EncryptUtil.toMD5("1234"));
}
}