如何从 csv C# 对密码进行散列和加盐

How to hash and add salt to password from csv C#

我是一名完全不熟悉 C# 编程的学生。我目前正在使用 MVC 做一个小型安全项目。该项目: 允许用户上传包含帐户但不包含哈希和盐的密码的 csv 文件。 (完毕) 然后我会将文件发送到 virustotal 并在保存到服务器之前对其进行扫描(完成) 保存后,我需要将数据插入 csv 文件并将密码散列并加盐到数据库中。 (需要帮助)

我的控制器

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();
        }
    }
}
}

我的索引

@{
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>
}

上传

@{
ViewBag.Title = "Upload";
}

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

更改 SQL 语句并为其添加静态盐

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

假设不需要通过 SQL 进行批量插入:

由于您使用的是 ASP.NET,请使用 Crypto class 来散列您的密码:

var hashedPassword = Crypto.HashPassword(plainTextPassword);

以后要验证纯文本版本时,使用

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

散列密码包含散列时使用的盐,Crypto 知道如何从密码散列中提取盐。

因为你有一个流可以读取:

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();
    }
}

这还有一个优点是不需要将文件保存在任何地方,因为您可以只使用内存中已有的字节。