.NET Base64高级加密解密
.NET Base64高级加密解密
今天讲解一下,最近在项目中用到的高级Base64加密解密方法,使平常的Base64解密无法被破解。
实现原理
其实原理很简单,就是把普通的字符串进行常规的Base64加密,然后拿到加密后的值。通过一个方法,生成固定长度的随机字符,拼接在Base64字符串前,类似于这样:
// 案例
var base64Str = "JUsKZMjjAyMyTAM0MjcuMj2JmZJWU4MZWEUwMNTMyNDc4YyjkycZjVmOGjJiYjU5iNjUwMzAuMjkuyNTk5NDY2YNjkzjNzU4OTzc2";
var randomStr = "Etf21sGlHj";
var resultBase64 = $"{randomStr}{base64Str}";
当然你觉得这样就完了嘛?NO NO NO. 这样肯定是行不通的,很容易就被破解了。
所以这个时候我们就要涉及到一个字典,这个字典是我们自己去定义的一个常量。
字典?什么是字典,这里有人会问。其实字典就相当于汉语词典一样,一个字对应一个拼音,或者一个意思。而我们程序中的字典也一样,某个Key对应一个Value。
OK,现在我们加密后的Base64字符串也拿到了,字典也定义了,下面让我们看看具体的步骤。
- 定义一个常量字段,Int类型,其中的定义的值随意,看自己心情决定。
private const int RandomPrefixStrLength = 7;
- 定义一个常量字符串,用作你拿去随机值的源头。
private const string RandomStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- 定义一个从随机值源头得到 条件1 中定义的值长度的随机值的方法
GetRandomStr()
。 - 定义一个类,类中有两个字段,一个Key 一个Value,类定义具体看实现代码块。
- 定义一个List集合,类型为 条件4 中定义的类。然后设置 Key Value,这个随你心情来,只要保证不重复按照顺序就好。具体看代码块。
- 定义两个方法,用于将加密后的 Base64 的顺序按照 条件5 中定义的字典,进行打乱顺序。
另外一个方法用于将未解密的 Base64 的顺序按照 条件5 中定义的字段,进行恢复原有顺序。 - Base64 加密 定义一个 用于加密 字符串 的 扩展方法,扩展方法中,通过 条件3 生成一个随机字符串。把加密的字符串通过方法进行加密成 Base64 字符,通过 条件6 中的方法打乱顺序,然后把生成的随机字符串拼接在 需要加密后的字符串前面。
- Base64 解密 定义一个 用于解密 Base64字符串的 扩展方法,扩展方法中,根据 条件1 中定义的值,删除要解密字符串的前 X 位的值,然后通过 条件6 中的方法恢复顺序,然后通过方法解密 Base64字符串。
具体实现代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
/// <summary>
/// Base64 高级解密加密帮助类
/// </summary>
public static class Base64Helper
{
/// <summary>
/// 随机值生成的长度
/// </summary>
private const int RandomPrefixStrLength = 7;
/// <summary>
/// 生成随机值的源头
/// </summary>
private const string RandomStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/// <summary>
/// 字典信息类
/// </summary>
private struct PwdDicItem {
/// <summary>
/// Key
/// </summary>
public int Index { get; set; }
/// <summary>
/// Value
/// </summary>
public int RandomIndex { get; set; }
}
/// <summary>
/// 字典
/// </summary>
private static readonly List<PwdDicItem> dicList = new List<PwdDicItem>{
// 可以根据需求随意定义
new PwdDicItem {Index = 18, RandomIndex = 11},
new PwdDicItem {Index = 10, RandomIndex = 6},
new PwdDicItem {Index = 7, RandomIndex = 4},
new PwdDicItem {Index = 5, RandomIndex = 3},
new PwdDicItem {Index = 2, RandomIndex = 1}
};
/// <summary>
/// 得到随机值
/// </summary>
private static string GetRandomStr()
{
var result = "";
// 这边是定义随机数,()括号中的意思是最大值为当前时间,也就是Time
var random = new Random(Convert.ToInt32($"{DateTime.Now:HHmmssfff}"));
for (var i = 0; i < RandomPrefixStrLength ; i++)
{
var randomInt = random.Next(0, RandomStr.Length);
var randomChar = RandomStr[randomInt];
result += randomChar;
}
Thread.Sleep(1); // 休眠,以使随机数不重叠.
return result;
}
/// <summary>
/// 打乱Base64顺序
/// </summary>
private static string InsertRandomStrToBase64Str(string base64Str)
{
var strResult = $"{base64Str}";
dicList.ForEach(item =>
{
if (item.Index < base64Str.Length)
{
var randomChar = base64Str[item.RandomIndex];
strResult = strResult.Insert(item.Index, $"{randomChar}");
}
});
return strResult;
}
/// <summary>
/// 恢复打乱的Base64顺序
/// </summary>
private static string RemoveBase64StrRandomStr(string input)
{
var items = dicList.OrderBy(x => x.Index).ToList();
var strResult = $"{input}";
items.ForEach(item =>
{
if (item.Index < strResult.Length)
{
var randomChar = input[item.RandomIndex];
strResult = strResult.Remove(item.Index, 1);
}
});
return strResult;
}
/// <summary>
/// 普通 字符串 转换为 Base64 字符串
/// </summary>
public static string ToBase64(this string str)
{
if (string.IsNullOrWhiteSpace(str))
{
return "";
}
try
{
var randomPrefixStr = GetRandomStr();
var buffer = encoding.GetBytes(str);
var base64Str = Convert.ToBase64String(buffer);
base64Str = RandomPrefixStrLength == 0 ? base64Str : InsertRandomStrToBase64Str(base64Str);
return $"{randomPrefixStr}{base64Str}";
}
catch (Exception ex)
{
Console.WriteLine($"Base64Helper.ToBase64: {ex}");
}
return string.Empty;
}
/// <summary>
/// Base64 字符串 转换为 普通 字符串
/// </summary>
public static string Base64ToString(this string base64Str)
{
var result = base64Str.Trim();
try
{
if (string.IsNullOrWhiteSpace(base64Str?.Trim()))
{
return "";
}
base64Str = base64Str?.Trim();
var input = base64Str?.Substring(RandomPrefixStrLength);
input = RandomPrefixStrLength == 0 ? input : RemoveBase64StrRandomStr(input);
var buffer = Convert.FromBase64String(input);
result = encoding.GetString(buffer);
}
catch (Exception ex)
{
Console.WriteLine($"Base64Helper.Base64ToString: {ex}");
}
return result;
}
}
今天的学习就到这里吧~
当你的能力还不足以撑不起你的野心时,你就需要静下心来 好好学习。
When your abilities are not enough to support your ambitions, you need to calm down and study hard.