C #의 해시 문자열


94

에서 해시 문자열을 얻으려고 할 때 문제가 c#있습니다.

이미 몇 개의 웹 사이트를 시도했지만 대부분은 파일을 사용하여 해시를 얻습니다. 다른 문자열은 너무 복잡합니다. 다음과 같은 웹용 Windows 인증의 예를 찾았습니다.

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

파일 이름이 포함 된 문자열을보다 안전하게 만들려면 해시를 사용해야합니다. 어떻게 할 수 있습니까?

예:

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

"md5"가 아닌 다른 해싱 알고리즘을 사용해야합니까?

답변:


187
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

1
SCrypt를 사용하여이 예를 참조하십시오 stackoverflow.com/questions/20042977/...
무하마드 Rehan 사이드

6
@Muh SHA512보다 훨씬 빠르기 때문에 체크섬에 쉽게 사용할 수 있습니다. 그러나 실제로 암호를 저장하는 것은 권장되지 않습니다.
LuckyLikey

6
이것은 무엇을 b.ToString("X2")의미합니까?
Bilal Fazlani


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
또한 SHA1Managed입니다 IDisposable및 따라서로의 사용을 포장하는 데 필요한 using블록.
Earth Engine

목적 Dispose방법은 내부 버퍼를 지우는 것입니다. 그렇게하지 않으면 메모리 공격의 위험이 있습니다.
Earth Engine

3
@MuhammadRehanSaeed 내가 SHA1Managed비용이 많이 들지 않는다고 말했을 때 , 나는 그것의 창조가 아니라는 것을 의미합니다. 또한 해싱 알고리즘은 비용이 많이 들지 않습니다. 충돌을 찾고 싶을 때만 (매우) 비용이 많이 듭니다.
Earth Engine

1
@King_Fisher-불가능합니다! 해시는 단방향 함수이며 정보가 손실됩니다. 복호화가 필요한 경우 해싱이 아닌 암호화 방식을 사용해야합니다. BTW, 암호 암호화는 나쁜 습관입니다.
andrew.fox

8

나는 당신의 질문의 전체 범위를 정말로 이해하지 못하지만 필요한 모든 것이 문자열의 해시라면 그것을 얻는 것은 매우 쉽습니다.

GetHashCode 메서드를 사용하십시오.

이렇게 :

string hash = username.GetHashCode();

1
예, 그것이 무엇을 찾고 있는지. 하지만 코드는 큰 실수입니다. int hash = "username".GetHasCode ();
Edy Cu

3
사용자 이름을 큰 따옴표로 묶은 이유는 무엇입니까? 그러면 '사용자 이름'이라는 단어의 해시와 이제 사용자 이름 변수에있는 내용을 얻을 수 있습니다.
Cyril Gupta

15
GetHashCode의 값을 저장하지 마십시오. 32x와 64x에서 다릅니다
Slava

13
이것은 암호 해시를 만드는 잘못된 방법입니다. GetHashCode ()를 사용하면 다른 컴퓨터에서 동일한 번호가 생성 될 것이라고 가정 할 수 없습니다. Sha1 해시 방법 등을 사용합니다 (나중에 예제를 게시하겠습니다)
andrew.fox 2014 년

2
주목해야한다 GetHashCode안전한 암호화 해시 알고리즘이 아닙니다. 최소한 SHA256을 사용하거나 보안 알고리즘을 위해 BCrypt 또는 Scrypt를 더 잘 사용하십시오.
Muhammad Rehan Saeed

5

나는 당신이 찾고있는 것이 해싱이 아니라 암호화라고 생각합니다. 해싱을 사용하면 "hash"변수에서 원래 파일 이름을 검색 할 수 없습니다. 암호화를 사용하면 할 수 있으며 안전합니다.

.NET의 암호화에 대한 자세한 내용은 VB.NET 을 사용하는 ASP.NET의 AES를 참조하십시오 .


예, 암호화라고 생각하지만 결과 해시를 비교하고 싶습니다. 페이지 리디렉션 후.
Edy Cu

해시 된 파일 이름을 무엇과 비교 하시겠습니까?
Pieter van Ginkel

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를 더 잘 사용하십시오.
무하마드 Rehan 사이드

SCrypt를 사용하여이 예를 참조하십시오 stackoverflow.com/questions/20042977/...
무하마드 Rehan 사이드

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

가장 짧고 빠른 방법. 단 한 줄!

    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.