| using System; | 
| using System.Collections.Generic; | 
| using Top.Api.Util; | 
| using System.Text; | 
|   | 
|   | 
| namespace Top.Api.Security | 
| { | 
|   | 
|     public class SecurityBiz : SecurityConstants | 
|     { | 
|         private static IDictionary<string, Nullable<char>> SEPARATOR_CHAR_MAP = InitSeparatorCharMap(); | 
|         private static IDictionary<string, string> SEPARATOR_MAP = InitSeparatorMap(); | 
|   | 
|         private static IDictionary<string, Nullable<char>> InitSeparatorCharMap() | 
|         { | 
|             IDictionary<string, Nullable<char>> map = new Dictionary<string, Nullable<char>>(); | 
|             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<string, string> InitSeparatorMap() | 
|         { | 
|             IDictionary<string, string> map = new Dictionary<string, string>(); | 
|             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<string, Nullable<char>> GetSeparatorCharMap() | 
|         { | 
|             return SEPARATOR_CHAR_MAP; | 
|         } | 
|   | 
|         public static IDictionary<string, string> GetSeparatorMap() | 
|         { | 
|             return SEPARATOR_MAP; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 判断是否密文数据 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="type">加密字段类型(例如:simple\phone)</param> | 
|         /// <returns></returns> | 
|         public static bool IsEncryptData(string data, string type) | 
|         { | 
|             if (string.IsNullOrEmpty(data) || data.Length < 4) | 
|             { | 
|                 return false; | 
|             } | 
|   | 
|             Nullable<char> 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; | 
|         } | 
|   | 
|        /// <summary> | 
|         /// 判断是否密文数据 | 
|        /// </summary> | 
|        /// <param name="dataArray"></param> | 
|        /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 加密手机尾号后8位 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separator"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 加密手机后4位转H-MAC | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separator"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 手机号后4位H-MAC值 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separator"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|         /// <summary> | 
|         ///  生成密文数据 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separator"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         public static string EncryptNormal(string data, string separator, SecretContext secretContext) | 
|         { | 
|             return separator + SecurityUtil.AESEncrypt(data, secretContext.Secret) + separator + secretContext.SecretVersion | 
|                     + separator; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 滑窗加密 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="compressLen"></param> | 
|         /// <param name="slideSize"></param> | 
|         /// <param name="separator"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         public static string EncryptNormalIndex(string data, int compressLen, int slideSize, string separator, | 
|                 SecretContext secretContext) | 
|         { | 
|             List<string> 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; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 密文检索 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="compressLen"></param> | 
|         /// <param name="slideSize"></param> | 
|         /// <param name="secretContext"></param> | 
|         /// <returns></returns> | 
|         public static string SearchNormalIndex(string data, int compressLen, int slideSize, SecretContext secretContext) | 
|         { | 
|             List<string> 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(); | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 获取秘钥版本、加密原始数据 | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separatorChar"></param> | 
|         /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 获取秘钥版本、加密原始数据(支持密文检索) | 
|         /// </summary> | 
|         /// <param name="data"></param> | 
|         /// <param name="separatorChar"></param> | 
|         /// <returns></returns> | 
|         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; | 
|         } | 
|   | 
|     } | 
| } |