C#のハッシュ文字列


91

でハッシュ文字列を取得しようとすると問題が発生しc#ます。

私はすでにいくつかのウェブサイトを試しましたが、それらのほとんどはハッシュを取得するためにファイルを使用しています。文字列用の他のものは少し複雑すぎます。次のようなWeb用のWindows認証の例を見つけました。

FormsAuthentication.HashPasswordForStoringInConfigFile(tbxPassword.Text.Trim(), "md5")

ファイル名を含む文字列をより安全にするために、ハッシュを使用する必要があります。どうやってやるの?

例:

string file  = "username";
string hash = ??????(username); 

「md5」ではなく、別のハッシュアルゴリズムを使用する必要がありますか?

回答:


183
using System.Security.Cryptography;

public static byte[] GetHash(string inputString)
{
    using (HashAlgorithm algorithm = SHA256.Create())
        return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

public static string GetHashString(string inputString)
{
    StringBuilder sb = new StringBuilder();
    foreach (byte b in GetHash(inputString))
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}

その他の注意事項

  • MD5とSHA1は廃止された安全でないアルゴリズムであるため、このソリューションではSHA256を使用します。別の方法としては、使用することができますbcryptのScryptをコメントで尖ったアウトとして。
  • また、コメントで指摘されているように、ハッシュを「ソルト」することを検討し、実績のある暗号化アルゴリズムを使用してください。

46
MD5またはSHA1は使用しないでくださいはしないでください。これらは廃止され、安全でないアルゴリズムです。少なくともSHA256を使用するか、BCryptまたはScryptを使用することをお勧めします。
Muhammad Rehan Saeed 2016

1
SCryptの使用例をご覧ください。 stackoverflow.com/questions/20042977/…–
Muhammad Saeed

6
@Muh SHA512よりもはるかに高速であるため、チェックサムに簡単に使用できます。しかし、実際にパスワードを保存することはお勧めできません。これは正しいことです。
LuckyLikey 2017

5
これはb.ToString("X2")どういう意味ですか?
Bilal Fazlani 2017年


60

パスワードストアの目的でハッシュ文字列を取得する最も速い方法は、次のコードです。

    internal static string GetStringSha256Hash(string text)
    {
        if (String.IsNullOrEmpty(text))
            return String.Empty;

        using (var sha = new System.Security.Cryptography.SHA256Managed())
        {
            byte[] textData = System.Text.Encoding.UTF8.GetBytes(text);
            byte[] hash = sha.ComputeHash(textData);
            return BitConverter.ToString(hash).Replace("-", String.Empty);
        }
    }

備考:

  • メソッドが頻繁に呼び出される場合は、sha変数の作成をクラスフィールドにリファクタリングする必要があります。
  • 出力はエンコードされた16進文字列として表示されます。

SHA1Managedクラスはそれほど高くありません。約130バイトを消費し、静的な値に初期化しますが、それだけです。したがって、ほとんどの場合、パフォーマンスの問題は発生しないはずです。
Earth Engine

1
また、その使用法をブロックにラップする必要SHA1ManagedIDisposableありusingます。
Earth Engine

目的のDispose方法は、内部バッファをクリアすることです。そうしないと、メモリ攻撃のリスクがあります。
Earth Engine

3
@MuhammadRehanSaeedSHA1Managedは、費用がかからないと言ったとき、その作成は費用がかからないことを意味します。また、ハッシュアルゴリズムはコストがかかる必要はありません。衝突を見つけたいときだけ、(非常に)コストがかかる必要があります。
Earth Engine

1
@ King_Fisher-それは不可能です!ハッシュは一方向性関数であり、情報は失われます。復号化する必要がある場合は、ハッシュではなく暗号化方式を使用する必要があります。ところで、パスワードの暗号化は悪い習慣です。
andrew.fox 2018

8

私はあなたの質問の全範囲を本当に理解していませんが、必要なのが文字列のハッシュだけである場合、それを取得するのは非常に簡単です。

GetHashCodeメソッドを使用するだけです。

このような:

string hash = username.GetHashCode();

1
はい、それは探しているものです。しかし、それは大きな間違いです。int hash = "username" .GetHasCode();のような書き込みを表示します。
Edy Cu

3
ユーザー名を二重引用符で囲むのはなぜですか?これにより、「username」という単語のハッシュが取得され、username変数の内容が取得されます。
Cyril Gupta

14
GetHashCodeからの値を保存しないでください。32xと64xでは異なります
Slava

12
これは、パスワードハッシュを作成するための悪い方法です。GetHashCode()を使用すると、異なるコンピューターで同じ番号が生成されると想定することはできません。Sha1ハッシュメソッドなどを使用します(後で例を投稿します)
andrew.fox 2014年

2
これはGetHashCode暗号的に安全なハッシュアルゴリズムではないことに注意してください。安全なアルゴリズムには、少なくともSHA256を使用するか、BCryptまたはScryptを使用することをお勧めします。
Muhammad Rehan Saeed 2016

5

あなたが探しているのはハッシュではなく暗号化だと思います。ハッシュを使用すると、「ハッシュ」変数から元のファイル名を取得できなくなります。暗号化を使用すると、安全です。

.NETでの暗号化の詳細については、VB.NET使用したASP.NETのAESを参照してください。


はい、暗号化だと思いますが、結果のハッシュを比較したいだけです。リダイレクトページの後。
Edy Cu

ハッシュされたファイル名を何と比較しますか?
Pieter van Ginkel 2010年

1
//Secure & Encrypte Data
    public static string HashSHA1(string value)
    {
        var sha1 = SHA1.Create();
        var inputBytes = Encoding.ASCII.GetBytes(value);
        var hash = sha1.ComputeHash(inputBytes);
        var sb = new StringBuilder();
        for (var i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }

3
このリンクからSHA1使用しないでください。SHA1は廃止された安全でないアルゴリズムです。少なくともSHA256を使用するか、BCryptまたはScryptを使用することをお勧めします。
Muhammad Rehan Saeed 2016

SCryptの使用例をご覧ください: stackoverflow.com/questions/20042977/…–
Muhammad

1

:パフォーマンスが主要な関心事ではない場合、あなたはまた、これらの方法のいずれかを使用することができます
(あなたが置き換え、大文字であることをハッシュ文字列を望んでいた場合"x2""X2"。)

public static string SHA256ToString(string s) 
{
    using (var alg = SHA256.Create())
        return string.Join(null, alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Select(x => x.ToString("x2")));
}

または:

public static string SHA256ToString(string s)
{            
    using (var alg = SHA256.Create())
        return alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString("x2"))).ToString();
}

0

これまでで最短かつ最速の方法。たった1行!

    public static string StringSha256Hash(string text) =>
        string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.