แฮชสตริงใน c #


93

ฉันมีปัญหาเมื่อพยายามดึงสตริงแฮชเข้าc#มา

ฉันลองใช้เว็บไซต์ไปแล้วสองสามแห่ง แต่ส่วนใหญ่ใช้ไฟล์เพื่อรับแฮช อื่น ๆ สำหรับสตริงนั้นซับซ้อนเกินไปเล็กน้อย ฉันพบตัวอย่างการรับรองความถูกต้องของ Windows สำหรับเว็บเช่นนี้:

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

ฉันต้องใช้แฮชเพื่อสร้างสตริงที่มีชื่อไฟล์ให้ปลอดภัยยิ่งขึ้น ฉันจะทำเช่นนั้นได้อย่างไร?

ตัวอย่าง:

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

ฉันควรใช้อัลกอริทึมการแฮชอื่นไม่ใช่ "md5" หรือไม่

คำตอบ:


185
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/…
Muhammad Rehan Saeed

6
@ มูสามารถใช้เช็คซัมได้อย่างง่ายดายเพราะเร็วกว่า 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ตัวแปรควรถูก refactored ในฟิลด์คลาส
  • เอาต์พุตแสดงเป็นสตริงฐานสิบหกที่เข้ารหัส

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

2
ควรสังเกตว่าGetHashCodeไม่ใช่อัลกอริทึมการแฮชที่มีการเข้ารหัสที่ปลอดภัย ใช้ SHA256 อย่างน้อยที่สุดหรือดีกว่าใช้ BCrypt หรือ Scrypt สำหรับอัลกอริทึมที่ปลอดภัย
Muhammad Rehan Saeed

5

ฉันคิดว่าสิ่งที่คุณกำลังมองหาไม่ใช่การแฮช แต่เป็นการเข้ารหัส ด้วยการแฮชคุณจะไม่สามารถเรียกชื่อไฟล์ต้นฉบับจากตัวแปร "แฮช" ได้ ด้วยการเข้ารหัสคุณสามารถทำได้และปลอดภัย

ดูAES ใน ASP.NET พร้อม VB.NETสำหรับข้อมูลเพิ่มเติมเกี่ยวกับการเข้ารหัสใน. NET


ใช่ฉันคิดว่าเป็นการเข้ารหัส แต่ฉันแค่ต้องการเปรียบเทียบแฮชผลลัพธ์ หลังจากเปลี่ยนเส้นทางหน้า
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
Muhammad Rehan Saeed

ดูตัวอย่างการใช้ SCrypt: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed

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.