1、前言
此为记录贴,记录一下Unity(C#)拉取服务器Json数据,访问服务器时加密密文进行传参访问,拉取数据时,进行对应的解密操作后,才看到可识别的Json数据,然后再进行解析。
2、流程
1、服务器端配置好Json数据和对应的加解密流程并给出对应的Url
2、按照服务器端的加密和解密过程,在本地写出一样的加密和解密过程(每种语言的加解密写法不一样)
3、按照服务器端约定好的秘钥和加密参数写好加解密流程后,再按照约定好访问Url时需要的传参,将参数放入字典再转为Json格式字符串,然后用写好的加密方法加密生成密文字符串,放到Url中再访问服务器,才能正确拉取到服务器的数据
4、上面一步拉取到的数据为经过加密后的字符串,需要解密。我们按照第二步写好的解密方法进行解密,得到正确的Json字符串,再根据字符串格式解析。
以下为我和服务器约定好的解密和解密流程,后面有对应的加密和解密代码(部分字符串为写的过程中测试用的名字,我太懒了,懒得改了,能跑就行哈哈)
解密过程:
1、把密文中‘-’替换成’+’,’’替换成’/’
2、判断替换后的密文长度,如果不是4的倍数,用‘=’补全
3、base64解密
4、aes解密,aes解密类型:aes-256-cbc,iv 为’0000000000000000’
加密过程:
1、aes加密
2、base64加密
3、’+’,’/‘,’=‘分别替换成’-‘,’‘,’’加密参数生成:
以pos为例,假如需要传userid=123,name=abc两个参数到服务器
1、把两个参数装到json字符串中,{“userid”:123,”name”:”abc”}
2、对json字符串加密
3、以mls为key,密文为value,进行请求
以下为加密和解密代码
/// <summary>
/// 加密
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public string TestEncript(string s)
{
string s2 = myEncrypt(s);
s2 = s2.Replace("+", "-");
s2 = s2.Replace("/", "_");
s2 = s2.Replace("=", "");
Debug.LogError("s2:" + s2);
return s2;
}
/// <summary>
/// 解密
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private string TestDecrypt(string s)
{
string test4 = s.Replace("-", "+").Replace("\n", "");
test4 = test4.Replace("_", "/");
while (test4.Length % 4 != 0)
{
test4 = test4 + "=";
}
// Debug.LogError("test4:" + test4);
string test2 = myDecrypt(test4);
// Debug.LogError("test2:" + test2);
return test2;
}
/// <summary>
/// AES加密
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string myEncrypt(string data)
{
byte[] bs = Encoding.UTF8.GetBytes(data);
RijndaelManaged aes256 = new RijndaelManaged();
aes256.Key = Encoding.UTF8.GetBytes("ccd9cd57fc5237a84dc63c2be044bc09"); //秘钥
aes256.Mode = CipherMode.CBC;
aes256.Padding = PaddingMode.PKCS7;
aes256.IV = Encoding.ASCII.GetBytes("0000000000000000"); //IV参数
return Convert.ToBase64String(aes256.CreateEncryptor().TransformFinalBlock(bs, 0, bs.Length)); //此处为 string Base64编码
}
/// <summary>
/// AES解密
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string myDecrypt(string data)
{
byte[] bs = Convert.FromBase64String(data); //此处为string Base64 解码
RijndaelManaged aes256 = new RijndaelManaged();
aes256.Key = Encoding.UTF8.GetBytes("ccd9cd57fc5237a84dc63c2be044bc09"); //秘钥
aes256.Mode = CipherMode.CBC;
aes256.Padding = PaddingMode.PKCS7;
aes256.IV = Encoding.ASCII.GetBytes("0000000000000000"); //IV参数
return Encoding.UTF8.GetString(aes256.CreateDecryptor().TransformFinalBlock(bs, 0, bs.Length));
}
以下为生成加密参数 urlEndText
public void Init()
{
version = Application.version;
string lang = LanguageManager.CurrentLangaugeCode.Substring(0,2);
Debug.LogError("language:" + lang);
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("version", version);
dic.Add("uuid", Game.Instance.PlayerUUID);
dic.Add("lang", lang);
string dicS = JsonConvert.SerializeObject(dic);
Debug.LogError("dics:" + dicS);
dicS = TestEncript(dicS);
urlEndText = "?mls=" + dicS; //此为加密参数,生成好后直接加到url后面去访问url即可
StartCoroutine(GetDailySignJson());
StartCoroutine(GetPassGameJsonInfo());
}
以下为用加密参数访问url,并解析解密和解析json的代码
public class RewardInfo
{
public string name { get; set; }
public int num { get; set; }
}
#region 每日签到
public class DailySignMonthData
{
public int status { get; set; }
public string msg { get; set; }
public List<DailySignMonthReward> data { get; set; }
}
public class DailySignMonthReward
{
public int id { get; set; }
public string start_time { get; set; }
public string end_time { get; set; }
public List<List<RewardInfo>> daily_prizes { get; set; }
public List<List<RewardInfo>> stage_prizes { get; set; }
}
public DailySignMonthData dailySignJsonInfo; //线上每日签到的json数据
public DailySignMonthReward nowMonthSignReward; //当前月份的每日签到数据
IEnumerator GetDailySignJson()
{
string url = string.Format("https://data.oceangazle.top/Merge/checkinReward{0}", urlEndText); //此url我就不用原url了
WWW www = new WWW(url);
yield return www;
if(www.text == null || www.text == "")
{
Debug.LogError("GetDailySignJson is null");
yield return null;
}
string decryptS = TestDecrypt(www.text);
Debug.LogError("Sign_decryptS:" + decryptS);
dailySignJsonInfo = JsonConvert.DeserializeObject<DailySignMonthData>(decryptS); //只需要将json的数据按照一一对应方式写出对应的类,就能直接用此方法将json转化为本地类的数据
nowMonthSignReward = GetNowMonthReward();
}
原代码在这里,可以自行查看:https://download.csdn.net/download/qq_41789645/88112737
有什么错误或者不足欢迎指出。