using System; using System.Collections.Generic; using Top.Api.Util; using System.Text; namespace Top.Api.Security { public class SecurityBiz : SecurityConstants { private static IDictionary> SEPARATOR_CHAR_MAP = InitSeparatorCharMap(); private static IDictionary SEPARATOR_MAP = InitSeparatorMap(); private static IDictionary> InitSeparatorCharMap() { IDictionary> map = new Dictionary>(); map.Add(NICK, SIMPLE_CHAR); map.Add(RECEIVER_NAME, SIMPLE_CHAR); map.Add(NORMAL, NORMAL_SEPARATOR_CHAR); map.Add(PHONE, PHONE_SEPARATOR_CHAR); map.Add(SIMPLE, SIMPLE_CHAR); map.Add(SEARCH, SIMPLE_CHAR); return map; } private static IDictionary InitSeparatorMap() { IDictionary map = new Dictionary(); map.Add(NICK, SIMPLE_SEPARATOR); map.Add(RECEIVER_NAME, SIMPLE_SEPARATOR); map.Add(NORMAL, NORMAL_SEPARATOR); map.Add(PHONE, PHONE_SEPARATOR); map.Add(SIMPLE, SIMPLE_SEPARATOR); map.Add(SEARCH, SIMPLE_SEPARATOR); return map; } public static IDictionary> GetSeparatorCharMap() { return SEPARATOR_CHAR_MAP; } public static IDictionary GetSeparatorMap() { return SEPARATOR_MAP; } /// /// 判断是否密文数据 /// /// /// 加密字段类型(例如:simple\phone) /// public static bool IsEncryptData(string data, string type) { if (string.IsNullOrEmpty(data) || data.Length < 4) { return false; } Nullable charValue = null; SEPARATOR_CHAR_MAP.TryGetValue(type, out charValue); if (charValue == null) { throw new SecretException("type error"); } char separatorChar = charValue.Value; if (!(data[0] == charValue && data[data.Length - 1] == charValue)) { return false; } if (separatorChar == PHONE_SEPARATOR_CHAR) { // 拆分元素 string[] dataArray = StringUtil.Split(data, separatorChar); if (dataArray.Length != 3) { return false; } if (data[data.Length - 2] == separatorChar) { return CheckEncryptData(dataArray); } else { string version = dataArray[dataArray.Length - 1]; if (StringUtil.IsNumeric(version)) { bool isBase64Value = SecurityUtil.IsBase64Value(dataArray[dataArray.Length - 2]); if (isBase64Value) { return true; } return false; } } } else { // 拆分元素 string[] dataArray = StringUtil.Split(data, separatorChar); if (data[data.Length - 2] == separatorChar) { if (dataArray.Length != 3) { return false; } return CheckEncryptData(dataArray); } else { if (dataArray.Length != 2) { return false; } return CheckEncryptData(dataArray); } } return false; } /// /// 判断是否密文数据 /// /// /// private static bool CheckEncryptData(string[] dataArray) { string version = dataArray[dataArray.Length - 1]; if (StringUtil.IsNumeric(version)) { bool isBase64Value = SecurityUtil.IsBase64Value(dataArray[0]); if (isBase64Value) { if (dataArray.Length == 3) { isBase64Value = SecurityUtil.IsBase64Value(dataArray[1]); if (isBase64Value) { return true; } } else { return true; } } } return false; } /// /// 加密手机尾号后8位 /// /// /// /// /// public static string EncryptPhone(string data, string separator, SecretContext secretContext) { if (data.Length < 11) { return data; } string prefixNumber = data.Substring(0, data.Length - 8); // 取后8位置 string last8Number = data.Substring(data.Length - 8); return separator + prefixNumber + separator + SecurityUtil.AESEncrypt(last8Number, secretContext.Secret) + separator + secretContext.SecretVersion + separator; } /// /// 加密手机后4位转H-MAC /// /// /// /// /// public static string EncryptPhoneIndex(string data, string separator, SecretContext secretContext) { if (data.Length < 11) { return data; } // 取后4位 string last4Number = data.Substring(data.Length - 4); return separator + SecurityUtil.HmacMD5EncryptToBase64(last4Number, secretContext.Secret) + separator + SecurityUtil.AESEncrypt(data, secretContext.Secret) + separator + secretContext.SecretVersion + separator + separator; } /// /// 手机号后4位H-MAC值 /// /// /// /// /// public static string SearchPhoneIndex(string data, string separator, SecretContext secretContext) { if (data.Length != 4) { throw new SecretException("phoneNumber error"); } return separator + SecurityUtil.HmacMD5EncryptToBase64(data, secretContext.Secret) + separator; } /// /// 生成密文数据 /// /// /// /// /// public static string EncryptNormal(string data, string separator, SecretContext secretContext) { return separator + SecurityUtil.AESEncrypt(data, secretContext.Secret) + separator + secretContext.SecretVersion + separator; } /// /// 滑窗加密 /// /// /// /// /// /// /// public static string EncryptNormalIndex(string data, int compressLen, int slideSize, string separator, SecretContext secretContext) { List slideList = SecurityUtil.GetSlideWindows(data, slideSize); StringBuilder builder = new StringBuilder(); foreach (string slide in slideList) { builder.Append(SecurityUtil.HmacMD5EncryptToBase64(slide, secretContext.Secret, compressLen)); } return separator + SecurityUtil.AESEncrypt(data, secretContext.Secret) + separator + builder.ToString() + separator + secretContext.SecretVersion + separator + separator; } /// /// 密文检索 /// /// /// /// /// /// public static string SearchNormalIndex(string data, int compressLen, int slideSize, SecretContext secretContext) { List slideList = SecurityUtil.GetSlideWindows(data, slideSize); StringBuilder builder = new StringBuilder(); foreach (string slide in slideList) { builder.Append(SecurityUtil.HmacMD5EncryptToBase64(slide, secretContext.Secret, compressLen)); } return builder.ToString(); } /// /// 获取秘钥版本、加密原始数据 /// /// /// /// public static SecretData GetSecretData(string data, char separatorChar) { SecretData secretData = null; if (PHONE_SEPARATOR_CHAR == separatorChar) { string[] dataArray = StringUtil.Split(data, separatorChar); if (dataArray.Length != 3) { return null; } string version = dataArray[2]; if (StringUtil.IsNumeric(version)) { secretData = new SecretData(); secretData.OriginalValue = dataArray[0]; ;// 手机号码前缀 secretData.OriginalBase64Value = dataArray[1]; secretData.SecretVersion = Convert.ToInt64(version); } } else { string[] dataArray = StringUtil.Split(data, separatorChar); if (dataArray.Length != 2) { return null; } string version = dataArray[1]; if (StringUtil.IsNumeric(version)) { secretData = new SecretData(); secretData.OriginalBase64Value = dataArray[0]; secretData.SecretVersion = Convert.ToInt64(version); } } return secretData; } /// /// 获取秘钥版本、加密原始数据(支持密文检索) /// /// /// /// public static SecretData GetIndexSecretData(string data, char separatorChar) { SecretData secretData = null; if (PHONE_SEPARATOR_CHAR == separatorChar) { string[] dataArray = StringUtil.Split(data, separatorChar); if (dataArray.Length != 3) { return null; } string version = dataArray[2]; if (StringUtil.IsNumeric(version)) { secretData = new SecretData(); secretData.OriginalValue = dataArray[0];// H-MAC(手机号码后4位) secretData.OriginalBase64Value = dataArray[1]; secretData.SecretVersion = Convert.ToInt64(version); } } else { string[] dataArray = StringUtil.Split(data, separatorChar); if (dataArray.Length != 3) { return null; } string version = dataArray[2]; if (StringUtil.IsNumeric(version)) { secretData = new SecretData(); secretData.OriginalBase64Value = dataArray[0]; secretData.OriginalValue = dataArray[1];// H-MAC value secretData.SecretVersion = Convert.ToInt64(version); } } if (secretData == null) { return secretData; } secretData.Search = true; return secretData; } } }