using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace BF
{
///
/// 资源加密
/// 考虑到效率效果
/// MAX_ENCRYPT_LEN之前的数据使用aes加密
/// MAX_ENCRYPT_LEN之后的数据使用混淆
///
public class ResourcesProtect
{
const int MAX_ENCRYPT_LEN = 512; //最大Aes加密长度,超过部分按规则混合
const int CONFUSE_OFFSET = 16; //混淆间隔
const int BLOCK_SIZE = 16; //校准对齐基数
///
/// 加密资源文件
///
static public void DoEncrypt(string resPath, string key, string desPath, Func filter = null)
{
if (null != filter && !filter(resPath))
return;
byte[] buffer = Read(resPath);
byte[] encryptBuffer = ExecuteEncrypt(buffer, key);
Write(encryptBuffer, desPath);
}
///
/// 解密资源文件
///
static public void DoDecrypt(string resPath, string key, string desPath, Func filter = null)
{
if (null != filter && !filter(resPath))
return;
byte[] buffer = Read(resPath);
byte[] decryptBuffer = ExecuteDecrypt(buffer, key);
Write(decryptBuffer, desPath);
}
static public byte[] Read(string resPath)
{
byte[] buffer = null;
try
{
FileStream stream = new FileStream(resPath, FileMode.Open);
if (null != stream)
{
BinaryReader reader = new BinaryReader(stream, Encoding.UTF8);
buffer = reader.ReadBytes((int)stream.Length);
stream.Close();
stream.Dispose();
reader.Close();
}
}
catch (Exception)
{
throw;
}
return buffer;
}
static public void Write(byte[] buffer, string resPath)
{
try
{
FileStream stream = new FileStream(resPath, FileMode.Create);
if (null != stream)
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(buffer, 0, buffer.Length);
stream.Close();
stream.Dispose();
writer.Close();
}
}
catch (Exception)
{
throw;
}
}
///
/// aes加混淆加密接口
///
static public byte[] ExecuteEncrypt(byte[] buffer, string key)
{
//这里后续附加混淆规则
int bufferLen = buffer.Length;
if (bufferLen > MAX_ENCRYPT_LEN)
{
//规定 ECBMode:(明文长度/16 + 1) * 16 = 密文长度
int retLen = bufferLen - MAX_ENCRYPT_LEN + (MAX_ENCRYPT_LEN / BLOCK_SIZE + 1) * BLOCK_SIZE;
byte[] encryBuffer = new byte[MAX_ENCRYPT_LEN];
byte[] retBuffer = new byte[retLen];
Array.Copy(buffer, encryBuffer, MAX_ENCRYPT_LEN);
byte[] beEncryBuffer = AesEncrypt.Encrypt(encryBuffer, key);
beEncryBuffer.CopyTo(retBuffer, 0);
Array.Copy(buffer, MAX_ENCRYPT_LEN, retBuffer, beEncryBuffer.Length, bufferLen - MAX_ENCRYPT_LEN);
for (int i = beEncryBuffer.Length, j = 0; i < retBuffer.Length; i += CONFUSE_OFFSET)
{
retBuffer[i] += buffer[j];
j += 2;
if (j >= MAX_ENCRYPT_LEN)
j = 0;
}
return retBuffer;
}
else
{
return AesEncrypt.Encrypt(buffer, key);
}
}
///
/// aes加混淆解密接口
///
static public byte[] ExecuteDecrypt(byte[] buffer, string key)
{
//这里后续附加混淆规则
int bufferLen = buffer.Length;
if (bufferLen > MAX_ENCRYPT_LEN)
{
//规定 ECBMode:(明文长度/16 + 1) * 16 = 密文长度
int decryLen = (MAX_ENCRYPT_LEN / BLOCK_SIZE + 1) * BLOCK_SIZE;
byte[] decryBuffer = new byte[decryLen];
Array.Copy(buffer, decryBuffer, decryLen);
byte[] beDecryBuffer = AesEncrypt.Decrypt(decryBuffer, key);
int retLen = bufferLen - decryLen + beDecryBuffer.Length;
byte[] retBuffer = new byte[retLen];
beDecryBuffer.CopyTo(retBuffer, 0);
Array.Copy(buffer, decryLen, retBuffer, beDecryBuffer.Length, retBuffer.Length - beDecryBuffer.Length);
for (int i = beDecryBuffer.Length, j = 0; i < retLen; i += CONFUSE_OFFSET)
{
retBuffer[i] -= beDecryBuffer[j];
j += 2;
if (j >= beDecryBuffer.Length)
j = 0;
}
return retBuffer;
}
else
{
return AesEncrypt.Decrypt(buffer, key);
}
}
}
}