package com.zdcf.tool;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.regex.Pattern;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.codecs.Codec;
import org.owasp.esapi.codecs.MySQLCodec;
import org.springframework.ui.ModelMap;
public class SecurityUtil {
private static final char hexDigits[] = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static final char hexDigitsabc[] = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static String LOGIN_SALT = "kaKNLKN:LKSDFDSF";
private static final Codec MYSQL_CODEC = new MySQLCodec(MySQLCodec.Mode.STANDARD);
public static final String escapeMySQL(String source){
return ESAPI.encoder().encodeForSQL(MYSQL_CODEC, source);
}
public static final String encodeForHTML(String source){
return ESAPI.encoder().encodeForHTML(source);
}
public static final String encodeForHTMLAttribute(String source){
return ESAPI.encoder().encodeForHTMLAttribute(source);
}
public static void validateReturnURL(ModelMap model, String siteURL, String returnURL){
if(SecurityUtil.isValidURL(siteURL, returnURL)){
model.addAttribute("returnURL", SecurityUtil.encodeForHTMLAttribute(returnURL));
} else {
model.addAttribute("returnURL", null);
}
}
public static boolean isValidURL(String siteURL, String target){
// http://dai.pinganziben.com/reg?returnURL=http://dai.pinganziben.com
// http://dai.pinganziben.com/reg?returnURL=http://dai.pinganziben.com/main
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com/loan/detail/view/100150403000101
// http://dai.pinganziben.com/login?returnURL=http://202.168.1.1/loan/detail/view/100150403000101
if (target == null || target.trim() == "" || target.length() == 0) {
return false;
}else if (checkUrl(target)) {
return true;
} else {
int index_1 = target.indexOf(".");
if(index_1 == -1 ){
return true;
}
if (target.substring(index_1) != null && target.substring(index_1).contains("/")) {
int index_2 = target.indexOf("/", index_1);
String domainName = target.substring(0, index_2);
String requestPath = target.substring(index_2);
// 正则表达式匹配 只能包含字母,数字和“/”且长度不能超过50个字符 : ^[/0-9a-z]{0,50}$
if (siteURL != null && siteURL.equalsIgnoreCase(domainName) && requestPath.matches("^[/0-9a-zA-Z]{0,70}$")) {
return true;
}
} else if (siteURL != null && siteURL.equalsIgnoreCase(target)) {
return true;
} else {
return false;
}
}
return false;
}
private static boolean checkUrl(String url){
String patternStr = "[A-Za-z0-9/]+";
return Pattern.matches(patternStr, url);
}
public static void main(String[] args){
//System.out.println(escapeMySQL("----''''\"\"-insert"));
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com
// http://dai.pinganziben.com/login?returnURL=http://123.57.76.59
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com/main
// http://dai.pinganziben.com/login?returnURL=http://123.57.76.59/mail
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com/loan/detail/view/100150403000101
// http://dai.pinganziben.com/login?returnURL=http://123.57.76.59/loan/detail/view/100150403000101
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com/loan/detail/view/"00150403000101
// http://dai.pinganziben.com/login?returnURL=http://123.57.76.59/loan/detail/view/"00150403000101
// http://dai.pinganziben.com/login?returnURL=http://dai.pinganziben.com/loan/detail/view/>00150403000101
// http://dai.pinganziben.com/login?returnURL=http://123.57.76.59/loan/detail/view/>00150403000101
String siteURL = "http://dai.pinganziben.com";
String[] testReturnURL = {
"http://dai.pinganziben.com", // valid returnURL
"http://123.57.76.59", // IP
"http://dai.pinganziben.com/main", // valid returnURL
"http://123.57.76.59/mail", // IP
"http://dai.pinganziben.com/loan/detail/view/100150403000101", // valid returnURL
"http://123.57.76.59/loan/detail/view/100150403000101", // IP
"http://dai.pinganziben.com/loan/detail/view/\"00150403000101", // contains """
"http://123.57.76.59/loan/detail/view/\"00150403000101", // contains """ with IP
"http://dai.pinganziben.com/loan/detail/view/>00150403000101", // contains ">"
"http://123.57.76.59/loan/detail/view/>00150403000101", // contains ">" with IP
"http://dai.pinganziben.com/loan/detail/view/00150403000101000000000000000000", // 50 characters, valid returnURL
"http://dai.pinganziben.com/loan/detail/view/001504030001010000000000000000000" // 51 characters
};
boolean[] isValid = {false, false, false, false, false, false, false, false, false, false, false, false};
for (int i = 0; i < 12; i ++) {
isValid[i] = isValidURL(siteURL, testReturnURL[i]);
System.out.println("isValid[" + i+ "]: Test for \"" + testReturnURL[i] + "\" is " + Boolean.toString(isValid[i]).toUpperCase());
}
}
public static String secureMD5(String source) {
return secureMD5(source, LOGIN_SALT);
}
public static String secureMD5(String source, String salt) {
String md5 = source;
for (int i = 0; i < 100; i++) {
md5 = MD5(md5) + LOGIN_SALT;
}
return MD5(md5);
}
public final static String sha256(String source) {
try {
StringBuffer sb = new StringBuffer();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(source.getBytes("UTF-8"));
for (byte code : md.digest()){
String temp = Integer.toHexString(code & 0xff);
if (temp.length() == 1) {
sb.append("0");
} else {
sb.append(temp);
}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public final static String secureSha256(String source, String salt) {
String sha = source;
for (int i = 0; i < 100; i++) {
sha = sha256(sha) + RandomUtil.code() + salt;
}
return sha256(sha);
}
public final static String MD5(byte[] btInput) {
try {
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public final static String md5abc(byte[] btInput) {
try {
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigitsabc[byte0 >>> 4 & 0xf];
str[k++] = hexDigitsabc[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public final static String md5abc(String s) {
return md5abc(s.getBytes());
}
public final static String MD5(String s) {
return MD5(s.getBytes());
}
public final static String MD5WithUtf8(String s) {
try {
return MD5(s.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}