using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace wanshu_api_demo
{
	/// <summary>
	/// 闪验后端服务置换手机号接口V2请求Demo示例
	/// </summary>
	public class FlashLoginDemo
	{


	    const string LOGIN_API_URL = "https://api.253.com/open/flashsdk/mobile-query";
	    
	
	    public static void Main(string[] args) {
	    	    	
	    	string appId="XXXXXXX"; //应用APPID
	    	string appKey="XXXXXXX";  //应用APPKEY
	    	string token="XXXXXX...";
	    	string outId="";
	    	string clientIp="";
	    	string encryptType="0";
	    	
	    	
	    	// 闪验sdk返回的参数
	    	IDictionary<string, string> dic = new Dictionary<string, string>();
	        dic.Add("appId", appId); 
			dic.Add("token", token); //SDK返回的token
			dic.Add("outId", outId); //客户流水号，可空
			dic.Add("clientIp", clientIp); //客户端IP，可空
			dic.Add("encryptType", encryptType);//手机号加密方式 0 ASE 1 RSA，可空 , 空则默认 0 AES加密
			
			//拼接请求参数，如不传字段可以不拼接进来，按字段名正序排列
			string requestStr="appId"+appId+"clientIp"+clientIp+"encryptType"+encryptType+"outId"+outId+"token"+token;
			//HmacSHA256签名
			string sign=HmacSHA256(requestStr,appKey);
			dic.Add("sign", sign);

	        string mobile=invokeApi(dic,appKey);
				
			Console.WriteLine("手机号:" + mobile);
			Console.ReadLine();
	    }
	
	
	    static string invokeApi(IDictionary<string, string> dic,string appKey) {
	        string mobile="";
	        
	        // 1.调用置换手机号api
	        Console.WriteLine(LOGIN_API_URL);	  
	        string result = HttpUtility.Post(LOGIN_API_URL, dic);
	        Console.WriteLine(result);	    
	        
	        JObject jsonObject =  string.IsNullOrEmpty(result) ? null : (JObject)JsonConvert.DeserializeObject(result);
			
	        // 2.处理返回结果
	        if (jsonObject != null) {
	            //响应code码。200000：成功，其他失败
	            string code = jsonObject["code"].ToString();
	            if ("200000".Equals(code) && null != jsonObject["data"]) {
	                // 调用成功
	                // 解析结果数据，进行业务处理
	                // 检测结果
	                Console.WriteLine("调用成功,data:" + jsonObject["data"].ToString());
	
	                string mobileName=jsonObject["data"]["mobileName"].ToString();
	                
	                //AES解密手机号
	                string key=MD5(appKey);
	                mobile=AesDecrypt(mobileName,key.Substring(0,16),key.Substring(16));
	                
	                //RSA解密手机号，如encryptType传1则使用此方式解密。
	                //mobile=RSADecrypt(xmlPrivateKey,mobileName); //xmlPrivateKey为客户私钥
	                
	            } else {
	                // 记录错误日志，正式项目中请换成log打印
	                Console.WriteLine("调用失败,code:" + code + ",msg:" +  jsonObject["message"]);
	            }
	        }
	        return mobile;
	    }
	    
	    public static string HmacSHA256(string message, string secret)
        {
            var encoding = new System.Text.UTF8Encoding();
            byte[] keyByte = encoding.GetBytes(secret);
            byte[] messageBytes = encoding.GetBytes(message);
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < hashmessage.Length; i++)
                {
                    builder.Append(hashmessage[i].ToString("x2"));
                }
                return builder.ToString();
            }
        }
	    
	    
	    public static string AesDecrypt(string data,string key, string iv)
        {
            if (string.IsNullOrEmpty(data))
            {
                throw new ArgumentException("data is empty.");
            }
			
            if (key == null || iv == null)
            {
                throw new ArgumentException("Key/Iv is null.");
            }

            byte[] bkey=System.Text.Encoding.Default.GetBytes ( key );
            byte[] biv=System.Text.Encoding.Default.GetBytes ( iv );
            	
            using (var rijndaelManaged = new RijndaelManaged() { Key = bkey, IV = biv, KeySize = 256,
                BlockSize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7})
            {
                using (var transform = rijndaelManaged.CreateDecryptor(bkey, biv))
                {
                    var inputBytes = StrToHexByte(data);
                    var encryptedBytes = transform.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
                    return Encoding.UTF8.GetString(encryptedBytes);
				}
            }
        }

		
		public static byte[] StrToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
		
		public static string ToHexString(byte[] bytes)
        {
            string hexString = string.Empty;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();
                for (int i = 0; i < bytes.Length; i++)
                {
                    strB.Append(bytes[i].ToString("X2"));
                }
                hexString = strB.ToString();
            }
            return hexString;
        }
		
		public static string MD5(string data)
		{
			MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
			byte[] hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding("UTF-8").GetBytes(data));
			StringBuilder tmp = new StringBuilder();
			foreach (byte i in hashedDataBytes)
			{
			tmp.Append(i.ToString("x2"));
			}
			return tmp.ToString();
		}
		
		static string RSADecrypt(string xmlPrivateKey, string content)
		{
		    string decryptedContent = string.Empty;
		    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
		    {
		        rsa.FromXmlString(xmlPrivateKey);
		        byte[] decryptedData = rsa.Decrypt(StrToHexByte(content), false);
		        decryptedContent = Encoding.GetEncoding("gb2312").GetString(decryptedData);
		    }
		    return decryptedContent;
		}
	}
}
