2016-07-03 23 views
0

Ich bin ein Student völlig neu in C# -Programmierung. Ich mache gerade ein Mini-Sicherheitsprojekt mit MVC. Das Projekt: Benutzern erlauben, eine CSV-Datei hochzuladen, die Konten aber Kennwort nicht Hasch und Salz enthält. (Fertig) Dann werde ich die Datei Virustotal senden und scannen, bevor Sie auf dem Server speichern (Fertig) Nach dem Speichern muss ich die Daten in die CSV-Datei und Hash-und fügen Sie das Passwort in die Datenbank. (Hilfe nötig)Wie Hash und fügen Sie Salz zum Kennwort von Csv C#

mein Controller

public ActionResult Upload(HttpPostedFileBase file) 
    { 
     if (System.IO.Path.GetExtension(file.FileName).Equals(".csv")) 
     { 
      //{0} = Y, {1} = M, {2} = D, {3} = H, {4} = min, {5} = Sec 
      string datetime = string.Format("{0}{1}{2}-{3}{4}{5}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second); 
      string fileName = string.Format("{0}_{1}.csv", file.FileName.Substring(0, (file.FileName.Length - 4)), datetime); 
      var fileStream = new System.IO.MemoryStream(); 
      file.InputStream.CopyTo(fileStream); 

      var vtObj = new VirusTotal("%API KEY%"); 
      vtObj.UseTLS = true; 
      try 
      { 
       var fileResults = vtObj.ScanFile(fileStream, fileName); 
       var report = vtObj.GetFileReport(fileResults.ScanId); 

       int resPos = report.Positives; 

       if (resPos == 0) 
       { 
        string savePath = Server.MapPath("~/CSV/" + fileName); 
        file.SaveAs(savePath); 
        try 
        { 
         //removing the first row 
         insertDB(fileName, savePath); 
         ViewBag.error = "Updated successfully"; 
         return View(); 

        } 
        catch (Exception ex) 
        { 
         ViewBag.error = "Unable to update DB" + ex; 
         return View("Index"); 
        } 
       } 
       else 
       { 
        ViewBag.error = "Unable to upload"; 
        return View("Index"); 
       } 
      } 
      catch (Exception ex) 
      { 
       ViewBag.error = string.Format("Unable to upload | One min only can upload 4 times | {0} | {1}", ex, fileName); 
       return View("Index"); 
      } 
     } 
     else 
     { 
      ViewBag.error = "Unable to upload"; 
      return View("Index"); 
     } 
    } 

    public void insertDB(string fileName, string savePath) 
    { 

     using (DB01Entities dbc = new DB01Entities()) 
     { 
      string sql = string.Format(@"CREATE TABLE [dbo].[TempImport] 
             (
              Name varchar(255), 
              Password VARBINARY(50) 
             ) 

             bulk insert [dbo].[TempImport] from '%MyPATH%\CSV\{0}' with (ROWTERMINATOR = '\n') 

             INSERT INTO dbo.Employee 
             (
              Name 
              Password 
             ) 
             SELECT name 
             FROM  dbo.TempImport 

             DROP TABLE dbo.TempImport", fileName); 
      dbc.Database.ExecuteSqlCommand(sql); 
      dbc.SaveChanges(); 
     } 
    } 
} 
} 

Mein Index

@{ 
ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
<input type="file" name="File" id="file" accept=".csv"/> 
<input type="submit" value="Upload" /> 
<div class="error">@ViewBag.error</div> 
} 

hochladen

@{ 
ViewBag.Title = "Upload"; 
} 

<div class="success">@ViewBag.error</div> 
<a href="/Home/Index">Back to Index>></a> 

Antwort

1

eine Masseneinfügung über SQL Unter der Annahme, ist keine Voraussetzung:

Da Sie ASP.NET verwenden, verwenden Sie die Crypto Klasse Hash Ihre Passwörter:

var hashedPassword = Crypto.HashPassword(plainTextPassword); 

Wenn Sie später die Klartext-Version überprüfen möchten, verwenden Sie

bool matches = Crypto.VerifyHashedPassword(hashedPassword, plainTextPassword); 

Das Hash-Kennwort enthält das beim Hashen verwendete Salt, und Crypto kann das Salz aus dem Kennwort-Hash extrahieren.

Da Sie haben einen Strom von lesen:

using(var reader = new StreamReader(fileStream)) 
{ 
    using (DB01Entities dbc = new DB01Entities()) 
    { 
     while(reader.Peek != -1) 
     { 
      var parts = reader.ReadLine().Split(','); 
      var hashedPassword = Crypto.HashPassword(parts[1]); 
      dbc.Employees.Add(new Employee { Name = parts[0], Password = hashedPassword }); 
     } 

     dbc.SaveChanges(); 
    } 
} 

Dies hat auch den Vorteil, dass die Datei erfordert überall gespeichert werden, da Sie nur das Bytes verwenden, können Sie bereits im Speicher haben.

+0

Diese Lösung ist gut, sie verwendet 'Crypto.HashPassword', was eine sichere Methode ist, weil Es enthält Iteration des Hash. – zaph

+0

Hallo, aber ich kann String nicht in Byte [] umwandeln bei "Password = hashedPassword" –

-1

die SQL-Anweisung ändern und damit fügen Sie ein statisches Salz, um es

CREATE TABLE [dbo].[TempImport] (
Name varchar(50) 
Password varchar(50) 
) 
bulk insert [dbo].[TempImport] from '%Abs_Path%' with (ROWTERMINATOR = '\n') 
INSERT INTO dbo.Employee 
(
Name 
Password 
) 
SELECT Name, HASHBYTES('SHA1', (Password+'+_)(*&^%$#@!')) FROM dbo.TempImport 
DROP TABLE dbo.TempImport 
+1

Tun Sie dies nicht, nur das Hinzufügen eines Salzes bietet keine ausreichende Sicherheit mehr. Siehe OWASP (Open Web Application Security-Projekt) [Passwortspeicher-Spickzettel] (https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Leverage_an_adaptive_one-way_function). Siehe [Wie sichere Passwörter zu hacken, The Theory] (http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846) auf Sicherheit Stackexchange. – zaph

+1

1. Verwenden Sie nicht SHA-1, verwenden Sie eine SHA-2-Funktion wie SHA-256. 2. Verwenden Sie kein statisches Salz, jeder Eintrag, der das gleiche Passwort verwendet, hat das gleiche Salz. Wenn eines entdeckt wird, werden alle anderen ebenfalls angezeigt. Verwenden Sie ein zufälliges Salz, das ebenfalls in der Datenbank gespeichert ist. 3. Verketten Sie nicht nur das Salz, sondern verwenden Sie eine HMAC-Funktion. 4. Es ist notwendig, die Hashfunktion zu iterieren, da die Berechnung von Hashes sehr schnell ist. 5. Verwenden Sie Standard-Passwortableitungsfunktionen wie "Crypto.HashPassword", "PBKDF2", "password_hash", "bcrypt", Skript usw. – zaph