?? commonutil.java
字號:
package com.yayisoft.sso.util;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
/**
* TODO XXX 這些類要聲明Exception異常,否則將會暴露加密算法的細節(jié)!!!!!!
*
* @author mead
*
*/
public final class CommonUtil {
public static String getGuid() {
return java.util.UUID.randomUUID().toString();
}
public static String getStripsByApply(String apply) throws SSOException {
return CommonUtil.getDigest(apply);
}
public static String getTipsByTokon(String tokon) throws SSOException {
return CommonUtil.getDigest(tokon);
}
public static String getStripsByIntro(String intro) throws SSOException {
return CommonUtil.getDigest(intro);
}
public static boolean checkApply(String apply, String strips)
throws SSOException {
return CommonUtil.checkDigest(apply, strips);
}
public static boolean checkTips(String tokon, String tips)
throws SSOException {
return CommonUtil.checkDigest(tokon, tips);
}
public static boolean checkIntro(String intro, String strips)
throws SSOException {
return CommonUtil.checkDigest(intro, strips);
}
/**
* 加密用戶名,使用apply與intro
* apply與intro全是隨機的,這意味著無法重放apply攻擊Validate來獲取userName的規(guī)律
* 用apply來加密用戶名,意味著,無法重放intro,tokon,strips來攻擊Anchor()
*
* @param userName
* @param apply
* 申請書
* @param intro
* 介紹信
* @return
*/
public static String EncryptUser(String userName, String apply, String intro)
throws SSOException {
byte[] salt = CommonUtil.getSalt(intro, apply);
return CommonUtil.coding(userName, salt, Mode.ENCRYPT);
}
/**
* 解密用戶名
*
* @param userName
* @param apply
* @param intro
* @return
*/
public static String DecryptUser(String userName, String apply, String intro)
throws SSOException {
byte[] salt = CommonUtil.getSalt(intro, apply);
return CommonUtil.coding(userName, salt, Mode.DECRYPT);
}
private static boolean checkDigest(String info, String digest)
throws SSOException {
try {
MessageDigest alga = java.security.MessageDigest
.getInstance("SHA-1");
String text = info + Config.DIGEST_STEING;
alga.update(text.getBytes("UTF8"));
byte[] result = alga.digest();
String digString = CommonUtil.byte2string(result);
if (digString.equals(digest)) {
return true;
} else {
return false;
}
} catch (Exception ex) {
System.out.println("非法摘要算法");
SSOException ssoEx = new SSOException("摘要有錯誤");
throw ssoEx;
}
}
private static String getDigest(String info) throws SSOException {
try {
MessageDigest alga = java.security.MessageDigest
.getInstance("SHA-1");
String text = info + Config.DIGEST_STEING;
alga.update(text.getBytes("UTF8"));
byte[] result = alga.digest();
System.out.println("####輸入明文****"+info+"%%%%%%%%%%%%%%");
System.out.println("getDigest獲取簽名...");
CommonUtil.out(result);
return CommonUtil.byte2string(result);
} catch (Exception ex) {
System.out.println("非法摘要算法");
SSOException ssoEx = new SSOException("摘要有錯誤");
throw ssoEx;
}
}
/**
* 取鹽的方法:
* 從apply和intro中獲得,兩個都不能缺少!!!
* @param info
* @return
* @throws SSOException
*/
private static byte[] getSalt(String apply,String intro) throws SSOException {
try {
String info = apply +Config.SALT_STEING + intro;//Config.SALT_STEING;附加字符
MessageDigest alga = java.security.MessageDigest
.getInstance("SHA-1");
System.out.println(info+"成鹽因子是"+info);
alga.update(info.getBytes("UTF8"));
byte[] result = alga.digest();
byte[] ok = new byte[8];
int j = 2;//獲取方法
for(int i=0;i<8;i++){
ok[i] = result[j];
j+=2;
}
return ok;
} catch (Exception ex) {
System.out.println("getDigestInByteArray非法摘要算法");
SSOException ssoEx = new SSOException("getDigestInByteArray摘要有錯誤");
throw ssoEx;
}
}
private enum Mode {ENCRYPT, DECRYPT};
private static String coding(String text, byte[] salt,Mode m)throws SSOException {
try {
for(byte i : salt){
System.out.println("coding.驗證salt.i提前鹽粒子="+i);
}
char[] pswd = Config.PSWD_STRING.toCharArray();
PBEKeySpec pbks = new PBEKeySpec(pswd);
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey k = kf.generateSecret(pbks);
Cipher cp = Cipher.getInstance("PBEWithMD5AndDES");
PBEParameterSpec ps = new PBEParameterSpec(salt, 1000);
byte[] result;
if(m==Mode.ENCRYPT){
cp.init(Cipher.ENCRYPT_MODE, k, ps);
result = cp.doFinal(text.getBytes());
}else{
cp.init(Cipher.DECRYPT_MODE, k, ps);
result = cp.doFinal(CommonUtil.hex2byte(text.getBytes()));//解密模式,將密文(HEX)轉(zhuǎn)換為byte[],進行操作
}
// //將鹽和加密結(jié)果放在一起,作為密文
// FileOutputStream f = new FileOutputStream("PBEEnc.dat");
// f.write(salt);
// f.write(ctext);
// f.close();
System.out.print("coding的鹽是:");
CommonUtil.out(salt);
System.out.print("result的結(jié)果是:");
CommonUtil.out(result);
System.out.println("####################原文是:" + new String(text));
System.out.println("####################密文是:" + new String(result));
if(m==Mode.ENCRYPT){//如果是加密,將byte[]轉(zhuǎn)換為HEX,便于傳輸!!!
return CommonUtil.byte2hex(result);
}else{
return new String(result);
}
} catch (Exception e) {
System.out.println("getDigestInByteArray非法摘要算法"+e.getMessage());
SSOException ssoEx = new SSOException("getDigestInByteArray摘要有錯誤");
//e.printStackTrace();
throw ssoEx;
}
}
/**
* 拼接方式!!!非轉(zhuǎn)換
* @param b
* @return
*/
private static String byte2string(byte[] b){
StringBuffer sb = new StringBuffer();
for(byte i : b){
sb.append(i);
System.out.print(i);
}
return sb.toString();
}
/**
* java字節(jié)碼轉(zhuǎn)字符串
* @param b
* @return
*/
private static String byte2hex(byte[] b) { //一個字節(jié)的數(shù),
// 轉(zhuǎn)成16進制字符串
String hs = "";
String tmp = "";
for (int n = 0; n < b.length; n++) {
//整數(shù)轉(zhuǎn)成十六進制表示
tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (tmp.length() == 1) {
hs = hs + "0" + tmp;
} else {
hs = hs + tmp;
}
}
tmp = null;
return hs.toUpperCase(); //轉(zhuǎn)成大寫
}
/**
* 字符串轉(zhuǎn)java字節(jié)碼
* @param b
* @return
*/
private static byte[] hex2byte(byte[] b) {
if ((b.length % 2) != 0) {
throw new IllegalArgumentException("長度不是偶數(shù)");
}
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
String item = new String(b, n, 2);
// 兩位一組,表示一個字節(jié),把這樣表示的16進制字符串,還原成一個進制字節(jié)
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
b = null;
return b2;
}
private static void out(byte[] b) {
System.out.println("開始輸出消息摘要:\n\n");
for (byte i : b) {
System.out.print(i);
}
System.out.println("\n開消息摘要結(jié)束");
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -