如果僅僅只是通過MD5直接加密,不安全。彩虹表很容易破解。所以為了加入靜態鹽和動態鹽
public String encreptUrl(String url){
try {
byte[] salt = "JKDSPnBKYJ2E7kEg9mYSteK4AXE8ywUB96y8gjDFhfy".getBytes("UTF-8");
String checkSalt = "C2NkXy3ECJn9AcMB976DnBKYJ2E7kEg9mYSte";
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.reset();
messageDigest.update(salt);
byte[] bytes = url.getBytes("UTF-8");
byte[] encryptUrl = messageDigest.digest(bytes);
Base64 base64 = new Base64(true);
String semiFinishedProducts = new String(base64.encode(encryptUrl));
//加密url的長度我設定的6位. 加密的url取三位。剩下三位分別給靜態鹽1位和動態鹽2位
String urlKey = semiFinishedProducts.substring(0,3);
//位置可以在0-32位之間。這裡可以選擇位置。但是解密的時候就必須用同樣的位置
String staticSalt = md5Util(urlKey+checkSalt).substring(4,5);
String dynaSalt = md5Util(""+UUID.randomUUID()).substring(5,7);
String encrypted = urlKey+staticSalt+dynaSalt;
//標記量。用來加強短連結檢查.這裡輸出檢視下
String sig = md5Util(encrypted);
String domain = "www.baidu.com/";
String subDomain = "demo/";
String encryptedUrl = domain+subDomain+encrypted;
//把 sig ,encryptedUrl ,originalUrl,key。存到資料庫
return encryptedUrl;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public String getOriginUrl(String encrpetUrl,String sig){
encrpetUrl = encrpetUrl.substring(encrpetUrl.lastIndexOf("/")+1);
String key = encrpetUrl.substring(0,3);
String staticSalt = encrpetUrl.substring(3,4);
//和上面的檢查鹽一樣
String checkSalt = "C2NkXy3ECJn9AcMB976DnBKYJ2E7kEg9mYSte";
//靜態鹽檢查
String correctStaticSalt = md5Util(key+checkSalt).substring(4,5);
if (!staticSalt.equals(correctStaticSalt)){
return "error";
}
String correctSig = md5Util(encrpetUrl);
if (!sig.equals(correctSig)){
return "error";
}
//檢查完畢。 沒問題就通過key查詢資料庫。拿到原始url
return "true";
}
public String md5Util(String semiFinishedProducts){
MessageDigest lDigest = null;
try {
lDigest = MessageDigest.getInstance("MD5");
lDigest.update(semiFinishedProducts.getBytes());
BigInteger lHashInt = new BigInteger(1, lDigest.digest());
return String.format("%1$032X", lHashInt);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
但是這個演算法還是有可能會有hash衝突。而且位數越短越可能發生。最好設定6位以上
解決方法:覆蓋資料庫方法或者重新計算