C#实现各种Hash计算
涉及框架及库
自己在NuGet管理器里面安装即可
- BouncyCastle.Cryptography:是加密算法和协议的.NET实现。
目前支持可计算的类型
- BLAKE2B_160
- BLAKE2B_256
- BLAKE2B_384
- BLAKE2B_512
- BLAKE2S_128
- BLAKE2S_160
- BLAKE2S_224
- BLAKE2S_256
- BLAKE3_256
- DSTU7564_256
- DSTU7564_384
- DSTU7564_512
- GOST3411
- GOST3411_2012_256
- GOST3411_2012_512
- KECCAK_224
- KECCAK_256
- KECCAK_288
- KECCAK_384
- KECCAK_512
- MD2
- MD4
- MD5
- RIPEMD128
- RIPEMD160
- RIPEMD256
- RIPEMD320
- SHA_1
- SHA_224
- SHA_256
- SHA_384
- SHA_512
- SHA_512_224
- SHA_512_256
- SHA3_224
- SHA3_256
- SHA3_384
- SHA3_512
- SHAKE128_256
- SHAKE256_512
- SM3
- TIGER
- WHIRLPOOL
核心代码
- 根据对应的算法名称获取用以计算哈希的对象
var digest = DigestUtilities.GetDigest("md5");
- 将需要计算的字符串转换为字节数组
var pla = "1234";
var inBytes = Encoding.UTF8.GetBytes(pla);
其它数据源
- 文件
File.ReadAllBytes(filepath);
- Hex字符串
Hex.Decode(pla);
- Base64
Convert.FromBase64String(pla);
- Stream流
using (Stream stream = new MemoryStream())
{
stream.Read(inBytes, 0, (int)stream.Length);
}
- 计算Hash
// 获取输出字节数组大小
var outlen = digest.GetDigestSize();
// 实例化一个接受输出结果的字节数组
var outBytes = new byte[outlen];
// 数据搞里头
digest.BlockUpdate(inBytes, 0, inBytes.Length);
// 结果搞出来
digest.DoFinal(outBytes, 0);
// 打印Hash值
Console.WriteLine($"{Hex.ToHexString(outBytes)}");
完整可运行代码
private static string[] testDigests => new string []
{
"BLAKE2B_160",
"BLAKE2B_256",
"BLAKE2B_384",
"BLAKE2B_512",
"BLAKE2S_128",
"BLAKE2S_160",
"BLAKE2S_224",
"BLAKE2S_256",
"BLAKE3_256",
"DSTU7564_256",
"DSTU7564_384",
"DSTU7564_512",
"GOST3411",
"GOST3411_2012_256",
"GOST3411_2012_512",
"KECCAK_224",
"KECCAK_256",
"KECCAK_288",
"KECCAK_384",
"KECCAK_512",
"MD2",
"MD4",
"MD5",
"RIPEMD128",
"RIPEMD160",
"RIPEMD256",
"RIPEMD320",
"SHA_1",
"SHA_224",
"SHA_256",
"SHA_384",
"SHA_512",
"SHA_512_224",
"SHA_512_256",
"SHA3_224",
"SHA3_256",
"SHA3_384",
"SHA3_512",
"SHAKE128_256",
"SHAKE256_512",
"SM3",
"TIGER",
"WHIRLPOOL",
};
static void Main(string[] args)
{
IDigest digest = DigestUtilities.GetDigest("md5");
var pla = "1234";
var inBytes = Encoding.UTF8.GetBytes(pla);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write($"明文消息");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($":{pla}{Environment.NewLine}");
for (int i = 0; i < testDigests.Length; i++)
{
digest = DigestUtilities.GetDigest(testDigests[i]);
var outlen = digest.GetDigestSize();
var outBytes = new byte[outlen];
digest.BlockUpdate(inBytes, 0, inBytes.Length);
digest.DoFinal(outBytes, 0);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write($"{digest.AlgorithmName}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($":{Hex.ToHexString(outBytes)}");
}
Console.ReadKey();
}
运行结果:
BCrypt
直接上代码片段,应该不难理解
char[] pw = "123".ToCharArray();
byte[] salt = new byte[16];
var rng = new SecureRandom();
rng.NextBytes(salt);
var cost = 10;
var hash = OpenBsdBCrypt.Generate(pw, salt, cost);
var hash2 = OpenBsdBCrypt.Generate("2a", pw, salt, cost);
Console.WriteLine($"{hash}");
Console.WriteLine($"{hash2}");
目前支持的的版本有:2a、2b、2y(默认)
运行结果:
在线校验一遍
总结
- 注意Base64的转换,C#对Base64的格式检验的较为严格,可能会因为字符数不够或有非法字符,从而导致Base64在转换为字节数组时报错,需要修正一下格式。(方法自行百度)