如果仅仅只是通过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位以上
解决方法:覆盖数据库方法或者重新计算
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。