一、Unity RSA 加密数据 序列化和反序列化 通用方法
不对称加密方法
//-----------------------
// @Author GarFey
// @date 20190612
// @version 1.0
//-----------------------
using System;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Xml.Serialization;
public class RSAEncryptionDecrypt : MonoBehaviour
{
//公钥
private const string PublicRsaKey =
@"zKNV1AEbvGrTQyuat8kDhx4Z7HBmRX38GLYlgF1MM0/FFnGyyEccMkMfZV3dcO62fFVRAmEhgsvjAHwiJEL6sae73p5w/mxfRowkqZPm/bJaSwj5C1Z8cYqNwzu9AD+t3WVFvloL6wuRMH8G56XDb6tL7Q34VV0+zjGILpBRM0k=AQAB";
//私钥
private const string PrivateRsaKey =
@"zKNV1AEbvGrTQyuat8kDhx4Z7HBmRX38GLYlgF1MM0/FFnGyyEccMkMfZV3dcO62fFVRAmEhgsvjAHwiJEL6sae73p5w/mxfRowkqZPm/bJaSwj5C1Z8cYqNwzu9AD+t3WVFvloL6wuRMH8G56XDb6tL7Q34VV0+zjGILpBRM0k=AQAB
zOM8liykU3k3QUkXoLh6K++iEvCddVepn8f37ws3BTgO7ErH0o3B2Xbip+b5kP80Xv5kAAL3PVPy7KnCXZz8Iw==
/7AoTIoGw9sIqUdNaSxOPEQLiN1Y+O9UTecoCJHIasHb6VizoptSYHAiX2g7mbFuUrjLPaAfLuqhIiecn1rDow==cKCxm3Pq2SAXKcI+RNFkB2bxVywBwpFv4y+PsU4e7rWELoxlD+9xElPyAI5NvlErvtRksETxGDtfnI0tFTzItQ==hthdeHg2tyYV/EiZX8U5AXmVZ7nsyWRW3rrxFwvjWcIhe4AHRNOLb0bUKeLrw9Oabk/9B+QhbfnZvwyLAlO45w==rOGwQPcRCGeKEqnL/isp+8+wyj8vQ2naxcemI8swK4FX4VUTl78ZTq/2Z+HfuEGIrosUJUCQ3lFWDr0K8ucDeg==Czh7iMvkwvCSk/DMo34sqNiAMGQ7X10YmRxHsyGqf3fExUXHuU6Y37KpgovijAIy1F9zOS+tQDhAwrKLxrQ7fbAFKKOgBFi56YurjxSIKXbe5ivpvFQ9NhEobghavuCkq8yvZ36YZ5IIhCik1G8GKWIYA05sli5txkJIBtq8AWc=";
void Start()
{
List serList = new List();
string path = @"Test.xml";
//赋值
for (int i = 0; i < 5; i++)
{
serList.Add(new Information("名字" + i, 20 + i));
}
GeneralSerialize(serList, path, PublicRsaKey);
List serTest = GeneralDeserialize>(path, PrivateRsaKey);
//输出返回的值
foreach (var temp in serTest)
{
Debug.Log(temp.name);
Debug.Log(temp.age);
}
}
///
/// 加密序列化
///
/// 类型
/// 要序列化的对象
/// 保存路径
/// 公钥
void GeneralSerialize(T obj, string path, string publicKey)
{
if (string.IsNullOrEmpty(path)) return;
string data = null; //最后要保存的数据
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); //rsa类
rsa.FromXmlString(publicKey); //使用公钥加密
MemoryStream msMax = new MemoryStream();
MemoryStream msSub = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
xs.Serialize(msMax, obj); //序列化到内存
byte[] maxSize = msMax.GetBuffer();
msMax.Flush();
msMax.Position = 0; //如果没有,就不能Read
msMax.Read(maxSize, 0, maxSize.Length);
int maxLength = rsa.KeySize/8 - 11; //加密块最大长度限制
//如果数据超出maxLength,就要切割数据进行加密
if (maxSize.Length <= maxLength)
{
data = Convert.ToBase64String(rsa.Encrypt(maxSize, true)); //加密
}
else
{
byte[] buffer = new byte[maxLength];
msMax.Flush();
msMax.Position = 0;
int blockSize = msMax.Read(buffer, 0, maxLength);
while (blockSize > 0)
{
byte[] toEncrypt = new byte[blockSize];
Array.Copy(buffer, 0, toEncrypt, 0, blockSize);
byte[] crypToGraph = rsa.Encrypt(toEncrypt, false);
msSub.Write(crypToGraph, 0, crypToGraph.Length);//加密
blockSize = msMax.Read(buffer, 0, maxLength);
}
data = Convert.ToBase64String(msSub.ToArray());
}
Stream fs = File.Create(path);
StreamWriter sw = new StreamWriter(fs);
sw.Write(data); //写入XML文本保存
sw.Close();
fs.Close();
msSub.Close();
msMax.Close();
rsa.Clear();
}
///
/// 加密反序列化
///
/// 类型
/// 保存路径
/// 私钥
///
T GeneralDeserialize(string path, string privateKey)
{
if (string.IsNullOrEmpty(path)) return default(T);
string data = null;
byte[] decData = null;
XmlSerializer xs = new XmlSerializer(typeof(T));
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privateKey);//使用私钥解密
Stream fs = File.OpenRead(path);
StreamReader sr = new StreamReader(fs);
data = sr.ReadToEnd(); //读入数据
byte[] strTobyte = Convert.FromBase64String(data);
int maxSize = rsa.KeySize/8; //解密块最大长度限制
MemoryStream msMax = new MemoryStream(strTobyte);
MemoryStream msSub = new MemoryStream();
//如果数据超出maxLength,就要切割数据进行解密
if (strTobyte.Length <= maxSize)
{
decData = rsa.Decrypt(strTobyte, false); //解密
}
else
{
byte[] buffer = new byte[maxSize];
int blockSize = msMax.Read(buffer, 0, maxSize);
while (blockSize > 0)
{
byte[] toDecrypt = new byte[blockSize];
Array.Copy(buffer, 0, toDecrypt, 0, blockSize);
byte[] plainText = rsa.Decrypt(toDecrypt, false);//解密
msSub.Write(plainText, 0, plainText.Length);
blockSize = msMax.Read(buffer, 0, maxSize);
}
decData = msSub.ToArray();
}
MemoryStream msDes = new MemoryStream(decData); //将要反序列化的数据写入内存
T retObj = (T)xs.Deserialize(msDes); //反序列化
rsa.Clear();
msDes.Close();
msMax.Close();
msSub.Close();
return retObj;
}
}
public class Information
{
[XmlAttribute("名字")]
public string name;
[XmlAttribute("年龄")]
public int age;
public Information(string name, int age)
{
this.name = name;
this.age = age;
}
//必须要有
public Information() { }
}
二、在unity中可以使用c#自带的对称算法对数据进行加密
//-----------------------
// @Author GarFey
// @date 20190612
// @version 1.0
//-----------------------
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using UnityEngine;
public class StringEncryption{
//C#中对字符串加密解密(对称算法)
#region C#中对字符串加密解密(对称算法)
private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
///
/// DES加密字符串
///
/// 待加密的字符串
/// 加密密钥,要求为8位
/// 加密成功返回加密后的字符串,失败返回源串
public static string EncryptDES(string encryptString, string encryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
byte[] rgbIV = Keys;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
cStream.Close();
return Convert.ToBase64String(mStream.ToArray());
}
catch
{
return encryptString;
}
}
///
/// DES解密字符串
///
/// 待解密的字符串
/// 解密密钥,要求为8位,和加密密钥相同
/// 解密成功返回解密后的字符串,失败返源串
public static string DecryptDES(string decryptString, string decryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
byte[] rgbIV = Keys;
byte[] inputByteArray = Convert.FromBase64String(decryptString);
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
cStream.Close();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch
{
Debug.Log("catch");
return decryptString;
}
}
#endregion
//MD5不可逆加密
#region MD5不可逆加密
//32位加密
public string GetMD5_32(string s, string _input_charset)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(s));
StringBuilder sb = new StringBuilder(32);
for (int i = 0; i < t.Length; i++)
{
sb.Append(t.ToString("x").PadLeft(2, '0'));
}
return sb.ToString();
}
//16位加密
//16位加密
public static string GetMd5_16(string ConvertString)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
t2 = t2.Replace("-", "");
return t2;
}
#endregion
}
经测试都是可以用的,第一种加密需要一个自定义的key,解密需要key来解密。
第二种是常见的MD5加密算法,不可逆的,可用来存储用户密码等信息。