欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET6中哈希算法的簡(jiǎn)化用法的實(shí)現(xiàn)

 更新時(shí)間:2021年09月08日 09:40:57   作者:WeihanLi  
本文主要介紹了.NET 6中哈希算法的簡(jiǎn)化用法的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Intro

微軟在 .NET 6 中引入一些更簡(jiǎn)單的 API 來(lái)使用 HMAC 哈希算法(MD5/SHA1/SHA256/SHA384/SHA512)

微軟的叫法叫做 HMAC One-Shoot method, HMAC 算法在普通的哈希算法基礎(chǔ)上增加了一個(gè) key,通過(guò) key 提升了安全性,能夠有效避免密碼泄露被彩虹表反推出真實(shí)密碼, JWT(Json Web Token) 除了可以使用 RSA 方式外也支持使用 HMAC 。

New API

新增的 API 定義如下:

namespace System.Security.Cryptography { 
    public partial class HMACMD5 { 
        public static byte[] HashData(byte[] key, byte[] source); 
        public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source); 
        public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination); 
        public static bool TryHashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten); 
    } 
 
    public partial class HMACSHA1 { 
        public static byte[] HashData(byte[] key, byte[] source); 
        public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source); 
        public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination); 
        public static bool TryHashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten); 
    } 
 
    public partial class HMACSHA256 { 
        public static byte[] HashData(byte[] key, byte[] source); 
        public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source); 
        public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination); 
        public static bool TryHashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten); 
    } 
 
    public partial class HMACSHA384 { 
        public static byte[] HashData(byte[] key, byte[] source); 
        public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source); 
        public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination); 
        public static bool TryHashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten); 
    } 
 
    public partial class HMACSHA512 { 
        public static byte[] HashData(byte[] key, byte[] source); 
        public static byte[] HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source); 
        public static int HashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination); 
        public static bool TryHashData(ReadOnlySpan<byte> key, ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten); 
    } 
} 

Sample Before

在之前的版本中想要實(shí)現(xiàn)計(jì)算 HMAC 算法會(huì)比較復(fù)雜,之前實(shí)現(xiàn)了一個(gè) HashHelper 來(lái)封裝了常用的 Hash 算法和 HMAC 算法,HashHelper 部分代碼如下,完整代碼可以從 Github 獲取:https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Helpers/HashHelper.cs

/// <summary> 
/// 獲取哈希之后的字符串 
/// </summary> 
/// <param name="type">哈希類型</param> 
/// <param name="source">源</param> 
/// <param name="key">key</param> 
/// <param name="isLower">是否是小寫(xiě)</param> 
/// <returns>哈希算法處理之后的字符串</returns> 
public static string GetHashedString(HashType type, byte[] source, byte[]? key, bool isLower = false) 
{ 
    Guard.NotNull(source, nameof(source)); 
    if (source.Length == 0) 
    { 
        return string.Empty; 
    } 
    var hashedBytes = GetHashedBytes(type, source, key); 
    var sbText = new StringBuilder(); 
    if (isLower) 
    { 
        foreach (var b in hashedBytes) 
        { 
            sbText.Append(b.ToString("x2")); 
        } 
    } 
    else 
    { 
        foreach (var b in hashedBytes) 
        { 
            sbText.Append(b.ToString("X2")); 
        } 
    } 
    return sbText.ToString(); 
} 
 
/// <summary> 
/// 計(jì)算字符串Hash值 
/// </summary> 
/// <param name="type">hash類型</param> 
/// <param name="str">要hash的字符串</param> 
/// <returns>hash過(guò)的字節(jié)數(shù)組</returns> 
public static byte[] GetHashedBytes(HashType type, string str) => GetHashedBytes(type, str, Encoding.UTF8); 
 
/// <summary> 
/// 計(jì)算字符串Hash值 
/// </summary> 
/// <param name="type">hash類型</param> 
/// <param name="str">要hash的字符串</param> 
/// <param name="encoding">編碼類型</param> 
/// <returns>hash過(guò)的字節(jié)數(shù)組</returns> 
public static byte[] GetHashedBytes(HashType type, string str, Encoding encoding) 
{ 
    Guard.NotNull(str, nameof(str)); 
    if (str == string.Empty) 
    { 
        return Array.Empty<byte>(); 
    } 
    var bytes = encoding.GetBytes(str); 
    return GetHashedBytes(type, bytes); 
} 
 
/// <summary> 
/// 獲取Hash后的字節(jié)數(shù)組 
/// </summary> 
/// <param name="type">哈希類型</param> 
/// <param name="bytes">原字節(jié)數(shù)組</param> 
/// <returns></returns> 
public static byte[] GetHashedBytes(HashType type, byte[] bytes) => GetHashedBytes(type, bytes, null); 
 
/// <summary> 
/// 獲取Hash后的字節(jié)數(shù)組 
/// </summary> 
/// <param name="type">哈希類型</param> 
/// <param name="key">key</param> 
/// <param name="bytes">原字節(jié)數(shù)組</param> 
/// <returns></returns> 
public static byte[] GetHashedBytes(HashType type, byte[] bytes, byte[]? key) 
{ 
    Guard.NotNull(bytes, nameof(bytes)); 
    if (bytes.Length == 0) 
    { 
        return bytes; 
    } 
 
    HashAlgorithm algorithm = null!; 
    try 
    { 
        if (key == null) 
        { 
            algorithm = type switch 
            { 
                    HashType.SHA1 => new SHA1Managed(), 
                    HashType.SHA256 => new SHA256Managed(), 
                    HashType.SHA384 => new SHA384Managed(), 
                    HashType.SHA512 => new SHA512Managed(), 
                    _ => MD5.Create() 
            }; 
        } 
        else 
        { 
            algorithm = type switch 
            { 
                    HashType.SHA1 => new HMACSHA1(key), 
                    HashType.SHA256 => new HMACSHA256(key), 
                    HashType.SHA384 => new HMACSHA384(key), 
                    HashType.SHA512 => new HMACSHA512(key), 
                    _ => new HMACMD5(key) 
            }; 
        } 
        return algorithm.ComputeHash(bytes); 
    } 
    finally 
    { 
        algorithm.Dispose(); 
    } 
} 

使用示例如下:

HashHelper.GetHashedBytes(HashType.MD5, "test"); 
HashHelper.GetHashedBytes(HashType.MD5, "test".GetBytes()); 
HashHelper.GetHashedBytes(HashType.MD5, "test", "testKey"); 
HashHelper.GetHashedBytes(HashType.MD5, "test".GetBytes(), "testKey".GetBytes()); 
 
HashHelper.GetHashedString(HashType.MD5, "test"); 
HashHelper.GetHashedString(HashType.SHA1, "test".GetBytes()); 
HashHelper.GetHashedString(HashType.SHA256, "test", "testKey"); 
HashHelper.GetHashedString(HashType.MD5, "test".GetBytes(), "testKey".GetBytes()); 

New API Sample

有了新的 API 以后可以怎么簡(jiǎn)化呢,來(lái)看下面的示例:

var bytes = "test".GetBytes(); 
var keyBytes = "test-key".GetBytes(); 
 
// HMACMD5 
var hmd5V1 = HMACMD5.HashData(keyBytes, bytes); 
var hmd5V2 = HashHelper.GetHashedBytes(HashType.MD5, bytes, keyBytes); 
Console.WriteLine(hmd5V2.SequenceEqual(hmd5V1)); 
 
// HMACSHA1 
var hsha1V1 = HMACSHA1.HashData(keyBytes, bytes); 
var hsha1V2 = HashHelper.GetHashedBytes(HashType.SHA1, bytes, keyBytes); 
Console.WriteLine(hsha1V2.SequenceEqual(hsha1V1)); 
 
// HMACSHA256 
var hsha256V1 = HMACSHA256.HashData(keyBytes, bytes); 
var hsha256V2 = HashHelper.GetHashedBytes(HashType.SHA256, bytes, keyBytes); 
Console.WriteLine(hsha256V2.SequenceEqual(hsha256V1)); 
 
// HMACSHA384 
var hsha384V1 = HMACSHA384.HashData(keyBytes ,bytes); 
var hsha384V2 = HashHelper.GetHashedBytes(HashType.SHA384, bytes, keyBytes); 
Console.WriteLine(hsha384V2.SequenceEqual(hsha384V1)); 
 
// HMACSHA512 
var hsha512V1 = HMACSHA512.HashData(keyBytes ,bytes); 
var hsha512V2 = HashHelper.GetHashedBytes(HashType.SHA512, bytes, keyBytes); 
Console.WriteLine(hsha512V2.SequenceEqual(hsha512V1)); 

直接使用對(duì)應(yīng)的 HMAC 哈希算法的 HashData 方法即可,傳入對(duì)應(yīng)的 key 和 原始內(nèi)容就可以了,上面是和我們 HashHelper 封裝的方法進(jìn)行對(duì)比,看結(jié)果是否一致,都是一致的,輸出結(jié)果如下:

More

對(duì)于普通的哈希算法,微軟其實(shí)在 .NET 5 就已經(jīng)支持了上面的用法,可以嘗試一下下面的代碼:

var bytes = "test".GetBytes(); 
 
// MD5 
var md5V1 = MD5.HashData(bytes); 
var md5V2 = HashHelper.GetHashedBytes(HashType.MD5, bytes); 
Console.WriteLine(md5V2.SequenceEqual(md5V1)); 
 
// SHA1 
var sha1V1 = SHA1.HashData(bytes); 
var sha1V2 = HashHelper.GetHashedBytes(HashType.SHA1, bytes); 
Console.WriteLine(sha1V2.SequenceEqual(sha1V1)); 
 
// SHA256 
var sha256V1 = SHA256.HashData(bytes); 
var sha256V2 = HashHelper.GetHashedBytes(HashType.SHA256, bytes); 
Console.WriteLine(sha256V2.SequenceEqual(sha256V1)); 
 
// SHA384 
var sha384V1 = SHA384.HashData(bytes); 
var sha384V2 = HashHelper.GetHashedBytes(HashType.SHA384, bytes); 
Console.WriteLine(sha384V2.SequenceEqual(sha384V1)); 
 
// SHA512 
var sha512V1 = SHA512.HashData(bytes); 
var sha512V2 = HashHelper.GetHashedBytes(HashType.SHA512, bytes); 
Console.WriteLine(sha512V2.SequenceEqual(sha512V1)); 

很多時(shí)候我們可能都會(huì)要使用 MD5 或者 SHA1 之后的字符串,不知道為什么微軟沒(méi)有直接獲取一個(gè)字符串的方法,如果有這樣一個(gè)方法,就會(huì)更方便了,相比之后,感覺(jué)還是自己封裝的 HashHelper 使用起來(lái)更舒服一些,哈哈,這樣的靜態(tài)方法不夠抽象如果要?jiǎng)討B(tài)替換哈希算法代碼可能就有點(diǎn)...

References

https://github.com/dotnet/runtime/pull/53487
https://github.com/dotnet/runtime/issues/40012
https://github.com/dotnet/core/issues/6569#issuecomment-913876347
https://baike.baidu.com/item/hmac/7307543?fr=aladdin
https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/HashSample/Program.cs
https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Helpers/HashHelper.cs

到此這篇關(guān)于.NET 6中哈希算法的簡(jiǎn)化用法的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān).NET 6 哈希算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • asp.net實(shí)現(xiàn)調(diào)用帶有輸出參數(shù)的存儲(chǔ)過(guò)程實(shí)例

    asp.net實(shí)現(xiàn)調(diào)用帶有輸出參數(shù)的存儲(chǔ)過(guò)程實(shí)例

    這篇文章主要介紹了asp.net實(shí)現(xiàn)調(diào)用帶有輸出參數(shù)的存儲(chǔ)過(guò)程,結(jié)合實(shí)例形式分析了前端基于jQuery的ajax調(diào)用及后臺(tái)存儲(chǔ)過(guò)程調(diào)用的相關(guān)技巧,需要的朋友可以參考下
    2016-03-03
  • DataReader不能使用using的詳細(xì)示例

    DataReader不能使用using的詳細(xì)示例

    這篇文章主要介紹了DataReader不能使用using的詳細(xì)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Asp.net response對(duì)象與request對(duì)象使用介紹

    Asp.net response對(duì)象與request對(duì)象使用介紹

    這篇文章主要介紹了Asp.net response對(duì)象與request對(duì)象使用,需要的朋友可以參考下
    2014-04-04
  • ASP.NET Core中間件計(jì)算Http請(qǐng)求時(shí)間示例詳解

    ASP.NET Core中間件計(jì)算Http請(qǐng)求時(shí)間示例詳解

    這篇文章主要給大家介紹了關(guān)于ASP.NET Core中間件計(jì)算Http請(qǐng)求時(shí)間的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用ASP.NET Core具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • asp.net下經(jīng)典數(shù)據(jù)庫(kù)記錄分頁(yè)代碼

    asp.net下經(jīng)典數(shù)據(jù)庫(kù)記錄分頁(yè)代碼

    asp.net下經(jīng)典數(shù)據(jù)庫(kù)記錄分頁(yè)代碼...
    2007-04-04
  • .net mvc超過(guò)了最大請(qǐng)求長(zhǎng)度的解決方法

    .net mvc超過(guò)了最大請(qǐng)求長(zhǎng)度的解決方法

    這篇文章主要為大家詳細(xì)介紹了.net mvc超過(guò)了最大請(qǐng)求長(zhǎng)度的解決方法,限制文件上傳大小,感興趣的小伙伴們可以參考一下
    2016-07-07
  • 詳解.Net中字符串不變性與相等判斷的特殊場(chǎng)景

    詳解.Net中字符串不變性與相等判斷的特殊場(chǎng)景

    本文主要介紹了.Net中字符串不變性與相等判斷的特殊場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • .NET Core 1.0創(chuàng)建Self-Contained控制臺(tái)應(yīng)用

    .NET Core 1.0創(chuàng)建Self-Contained控制臺(tái)應(yīng)用

    這篇文章主要為大家詳細(xì)介紹了.NET Core 1.0創(chuàng)建Self-Contained控制臺(tái)應(yīng)用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 最新評(píng)論