.NET 6 でのハッシュ アルゴリズムの簡略化された使用

.NET 6 でのハッシュ アルゴリズムの簡略化された使用

[[422468]]

この記事はWeChatの公開アカウント「amazingdotnet」から転載したもので、著者はWeihanLiです。この記事を転載する場合は、amazingdotnet の公開アカウントにご連絡ください。

はじめに

Microsoft は、HMAC ハッシュ アルゴリズム (MD5/SHA1/SHA256/SHA384/SHA512) を使用するために、.NET 6 でいくつかのよりシンプルな API を導入しました。

Microsoft はこれを HMAC ワンショット方式と呼んでいます。HMAC アルゴリズムは、通常のハッシュ アルゴリズムにキーを追加することでセキュリティを向上させ、パスワードの漏洩やレインボー テーブルによる実際のパスワードの推測を効果的に防ぐことができます。RSA に加えて、JWT (Json Web Token) も HMAC の使用をサポートしています。

新しいAPI

新しく追加された API 定義は次のとおりです。

  1. 名前空間 System.Security.Cryptography {
  2. 公共 部分クラス HMACMD5 {
  3. 公共 静的byte[] HashData(byte[]キー、byte[] ソース);
  4. 公共 静的byte[] HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース);
  5. 公共 静的  int HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先);
  6. 公共  static bool TryHashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先、出力  int書き込まれたバイト数);
  7. }
  8.  
  9. 公共 部分クラス HMACSHA1 {
  10. 公共 静的byte[] HashData(byte[]キー、byte[] ソース);
  11. 公共 静的byte[] HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース);
  12. 公共 静的  int HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先);
  13. 公共  static bool TryHashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先、出力  int書き込まれたバイト数);
  14. }
  15.  
  16. 公共 部分クラス HMACSHA256 {
  17. 公共 静的byte[] HashData(byte[]キー、byte[] ソース);
  18. 公共 静的byte[] HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース);
  19. 公共 静的  int HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先);
  20. 公共  static bool TryHashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先、出力  int書き込まれたバイト数);
  21. }
  22.  
  23. 公共 部分クラス HMACSHA384 {
  24. 公共 静的byte[] HashData(byte[]キー、byte[] ソース);
  25. 公共 静的byte[] HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース);
  26. 公共 静的  int HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先);
  27. 公共  static bool TryHashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先、出力  int書き込まれたバイト数);
  28. }
  29.  
  30. 公共 部分クラス HMACSHA512 {
  31. 公共 静的byte[] HashData(byte[]キー、byte[] ソース);
  32. 公共 静的byte[] HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース);
  33. 公共 静的  int HashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先);
  34. 公共  static bool TryHashData(ReadOnlySpan<byte>キー、ReadOnlySpan<byte> ソース、Span<byte> 宛先、出力  int書き込まれたバイト数);
  35. }
  36. }

サンプル前

以前のバージョンでは、HMAC アルゴリズムの計算はより複雑でした。以前は、よく使用されるハッシュ アルゴリズムと HMAC アルゴリズムをカプセル化するために HashHelper が実装されていました。コードの HashHelper 部分は次のとおりで、完全なコードは Github から入手できます: https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Helpers/HashHelper.cs

  1. /// <要約>
  2. /// ハッシュ後の文字列を取得する
  3. /// </要約>
  4. /// <param name = "type" >ハッシュ型</param>
  5. /// <param name = "source" >ソース</param>
  6. /// <param name = "key" >キー</param>
  7. /// <param name = "isLower" >小文字ですか?</param>
  8. /// <戻り値>ハッシュアルゴリズム処理後の文字列</戻り値>
  9. 公共 静的文字列 GetHashedString(HashType type、byte[] source、byte[]? key 、bool isLower = false )
  10. {
  11. Guard.NotNull(ソース、ソース名));
  12. (source.Length == 0)の場合
  13. {
  14. 文字列を返します。空です。
  15. }
  16. var hashedBytes = GetHashedBytes(型、ソース、キー);
  17. var sbText = 新しい StringBuilder();
  18. if (isLower)
  19. {
  20. foreach (ハッシュバイト内の変数 b )
  21. {
  22. sbText.Append(b.ToString( "x2" ));
  23. }
  24. }
  25. それ以外 
  26. {
  27. foreach (ハッシュバイト内の変数 b )
  28. {
  29. sbText.Append(b.ToString( "X2" ));
  30. }
  31. }
  32. sbText.ToString()を返します
  33. }
  34.  
  35. /// <要約>
  36. /// 文字列ハッシュ値を計算する
  37. /// </要約>
  38. /// <param name = "type" >ハッシュ型</param>
  39. /// <param name = "str" ​​>ハッシュする文字列</param>
  40. /// <戻り値>ハッシュされたバイト配列</戻り値>
  41. 公共 静的byte[] GetHashedBytes(HashType type, string str) => GetHashedBytes(type, str, Encoding.UTF8);
  42.  
  43. /// <要約>
  44. /// 文字列ハッシュ値を計算する
  45. /// </要約>
  46. /// <param name = "type" >ハッシュ型</param>
  47. /// <param name = "str" ​​>ハッシュする文字列</param>
  48. /// <param name = "encoding" >エンコーディングタイプ</param>
  49. /// <戻り値>ハッシュされたバイト配列</戻り値>
  50. 公共 静的byte[] GetHashedBytes(HashType type, string str, Encoding エンコーディング)
  51. {
  52. Guard.NotNull(str、nameof(str));
  53. if (str == string.Empty)
  54. {
  55. Array.Empty<byte>()を返します
  56. }
  57. var bytes = encoding.GetBytes(str);
  58. GetHashedBytes(type, bytes) を返します
  59. }
  60.  
  61. /// <要約>
  62. /// ハッシュ後のバイト配列を取得する
  63. /// </要約>
  64. /// <param name = "type" >ハッシュ型</param>
  65. /// <param name = "bytes" >元のバイト配列</param>
  66. /// <戻り値></戻り値>
  67. 公共 静的byte[] GetHashedBytes(HashType type, byte[] bytes) => GetHashedBytes(type, bytes, null );
  68.  
  69. /// <要約>
  70. /// ハッシュ後のバイト配列を取得する
  71. /// </要約>
  72. /// <param name = "type" >ハッシュ型</param>
  73. /// <param name = "key" >キー</param>
  74. /// <param name = "bytes" >元のバイト配列</param>
  75. /// <戻り値></戻り値>
  76. 公共 静的byte[] GetHashedBytes(HashType type, byte[] bytes, byte[]? key )
  77. {
  78. Guard.NotNull(バイト、バイト名));
  79. (バイト長 == 0)の場合
  80. {
  81. バイトを返します
  82. }
  83.  
  84. HashAlgorithm アルゴリズム = null !;
  85. 試す
  86. {
  87. if (キー== null )
  88. {
  89. アルゴリズム = タイプスイッチ
  90. {
  91. HashType.SHA1 => 新しい SHA1Managed()、
  92. HashType.SHA256 => 新しい SHA256Managed()、
  93. HashType.SHA384 => 新しい SHA384Managed()、
  94. HashType.SHA512 => 新しい SHA512Managed()、
  95. _ => MD5.Create ()
  96. };
  97. }
  98. それ以外 
  99. {
  100. アルゴリズム = タイプスイッチ
  101. {
  102. HashType.SHA1 => 新しい HMACSHA1(キー)、
  103. HashType.SHA256 => 新しい HMACSHA256(キー)、
  104. HashType.SHA384 => 新しい HMACSHA384(キー)、
  105. HashType.SHA512 => 新しい HMACSHA512(キー)、
  106. _ => 新しい HMACMD5(キー)
  107. };
  108. }
  109. algorithm.ComputeHash(bytes)を返します
  110. }
  111. ついに
  112. {
  113. アルゴリズム.Dispose();
  114. }
  115. }

以下に使用例をいくつか示します。

  1. HashHelper.GetHashedBytes(HashType.MD5、 "テスト" );
  2. HashHelper.GetHashedBytes(HashType.MD5、 "テスト" .GetBytes());
  3. HashHelper.GetHashedBytes(HashType.MD5、 "テスト" "テストキー" );
  4. HashHelper.GetHashedBytes(HashType.MD5、 "test" .GetBytes()、 "testKey" .GetBytes());
  5.  
  6. HashHelper.GetHashedString(HashType.MD5、 "テスト" );
  7. HashHelper.GetHashedString(HashType.SHA1、 "テスト" .GetBytes());
  8. HashHelper.GetHashedString(HashType.SHA256、 "テスト" "テストキー" );
  9. HashHelper.GetHashedString(HashType.MD5、 "test" .GetBytes()、 "testKey" .GetBytes());

新しい API サンプル

新しい API でどのように簡素化できるでしょうか? 次の例を見てみましょう。

  1. var bytes = "テスト" .GetBytes();
  2. var keyBytes = "テストキー" .GetBytes();
  3.  
  4. // HMACMD5
  5. var hmd5V1 = HMACMD5.HashData(keyBytes, バイ​​ト);
  6. var hmd5V2 = HashHelper.GetHashedBytes(HashType.MD5、バイト、キーバイト);
  7. Console.WriteLine(hmd5V2.SequenceEqual(hmd5V1));
  8.  
  9. // HMACSHA1
  10. var hsha1V1 = HMACSHA1.HashData(keyBytes, バイ​​ト);
  11. var hsha1V2 = HashHelper.GetHashedBytes(HashType.SHA1、バイト、キーバイト);
  12. コンソールに行を書き込む。
  13.  
  14. // HMACSHA256
  15. var hsha256V1 = HMACSHA256.HashData(keyBytes, バイ​​ト);
  16. var hsha256V2 = HashHelper.GetHashedBytes(HashType.SHA256、バイト、キーバイト);
  17. コンソールに行を書き込む。
  18.  
  19. // HMACSHA384
  20. var hsha384V1 = HMACSHA384.HashData(keyBytes, バイ​​ト);
  21. var hsha384V2 = HashHelper.GetHashedBytes(HashType.SHA384、バイト、キーバイト);
  22. コンソールに行を書き込む。
  23.  
  24. // HMACSHA512
  25. var hsha512V1 = HMACSHA512.HashData(keyBytes, バイ​​ト);
  26. var hsha512V2 = HashHelper.GetHashedBytes(HashType.SHA512、バイト、キーバイト);
  27. コンソールに行を書き込む。

対応する HMAC ハッシュ アルゴリズムの HashData メソッドを使用し、対応するキーと元のコンテンツを渡すだけです。上記は、結果が一貫しているかどうかを確認するために、HashHelper カプセル化メソッドと比較したものです。一貫しています。出力結果は次のとおりです。

もっと

一般的なハッシュ アルゴリズムについては、Microsoft は実際にすでに .NET 5 で上記の使用方法をサポートしています。次のコードを試すことができます。

  1. var bytes = "テスト" .GetBytes();
  2.  
  3. //MD5
  4. var md5V1 = MD5.HashData(バイト);
  5. var md5V2 = HashHelper.GetHashedBytes(HashType.MD5、バイト);
  6. Console.WriteLine(md5V2.SequenceEqual(md5V1));
  7.  
  8. // SHA1
  9. var sha1V1 = SHA1.HashData(バイト);
  10. var sha1V2 = HashHelper.GetHashedBytes(HashType.SHA1, バイト);
  11. Console.WriteLine(sha1V2.SequenceEqual(sha1V1));
  12.  
  13. // SHA256
  14. var sha256V1 = SHA256.HashData(バイト);
  15. var sha256V2 = HashHelper.GetHashedBytes(HashType.SHA256、バイト);
  16. Console.WriteLine(sha256V2.SequenceEqual(sha256V1));
  17.  
  18. // SHA384
  19. var sha384V1 = SHA384.HashData(バイト);
  20. var sha384V2 = HashHelper.GetHashedBytes(HashType.SHA384, バイト);
  21. Console.WriteLine(sha384V2.SequenceEqual(sha384V1));
  22.  
  23. // SHA512
  24. var sha512V1 = SHA512.HashData(バイト);
  25. var sha512V2 = HashHelper.GetHashedBytes(HashType.SHA512, バイト);
  26. Console.WriteLine(sha512V2.SequenceEqual(sha512V1));

多くの場合、MD5 または SHA1 の後の文字列を使用する必要があります。Microsoft が文字列を直接取得する方法を提供しないのはなぜかわかりません。そのような方法があれば、より便利です。後者と比較すると、自己カプセル化された HashHelper を使用する方が快適です。ハハ、このような静的メソッドは抽象性が足りません。ハッシュ アルゴリズム コードを動的に置き換えたい場合は、少し...

参考文献

  • 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=アラジン
  • 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

<<:  研究により、ディープラーニングAIは乳がんリスクの予測に優れていることが判明

>>:  ドローンは人気があり、3つの主要なアプリケーションが農家の役に立つ

ブログ    
ブログ    

推薦する

AIが人間の職業を「置き換える」ためのロードマップ

昨日、私はこのような図を見ました。AI がどのように人間に取って代わるかを示すレベル図です。写真写真...

Google DeepMind共同創設者:2028年までに人類がAGIを達成する可能性は50%

10月31日、テクノロジー系ポッドキャスト「Dwarkesh Patel」によると、Googleの...

機械学習モデルのパフォーマンスを評価する方法

教師あり機械学習モデルを一日中トレーニングすることはできますが、そのパフォーマンスを評価しなければ、...

機械学習は簡単になっていますが、ソフトウェアエンジニアリングはまだ難しいです

これはレビュー記事です。 それは偏りもあります。 スペシャリストではなく、物事を作ったり問題を解決し...

AI が「脳で画像を完成させる」ことを学習: ニューラル ネットワークが 0 から 1 までの画像を完成させる

1新しいインテリジェンス集出典: arXiv、Github張毅編纂[新しいインテリジェンスの紹介]自...

...

これらの 10 個のオープンソース機械学習ツールを使用したことがありますか?

機械学習開発者として、あなたは多くの機械学習リソースに遭遇したことがあるかもしれません。今日は、オー...

マイクロソフトが27億パラメータのPhi-2モデルを発表、多くの大規模言語モデルを上回る性能を発揮

マイクロソフトは、Phi-2 と呼ばれる人工知能モデルをリリースしました。このモデルは、その 25 ...

メモリを3%~7%削減! Google がコンパイラ最適化のための機械学習フレームワーク MLGO を提案

現代のコンピュータの出現により、より高速でより小さなコードをコンパイルする方法が問題になりました。コ...

衝突の火花: ディープ AI とワイヤレス センシング (パート 1)

[[435758]]序文モノのインターネット (IoT) の発展により、さまざまな無線信号 (Wi...

機械学習アルゴリズム入門: 線形モデルからニューラルネットワークまで

最近、「機械学習」という言葉をよく耳にするようになりました(通常は予測分析や人工知能の文脈で)。過去...

デジタル経済時代の識別技術の新たな展開

青果市場では、小銭を気にせず、携帯電話をスワイプするだけで支払いができます。駅では、切符を買うために...

...

AIに対する期待や考え

[[398945]]中国ビジネスネットワーク特別コメンテーター、宋清輝(経済学者)最近、第5回世界知...

...