=x= 🌵 User Manager - Content Page 替後台管理者密码加盐加密。
📌 後台的所有页面建议可先上网找套版用的免费资源,由於要讲到密码加密,所以先从存资料开始,後面会再回头讲登入页如何验证密码,本篇重点在於使用 Argon2 替密码加盐後加密再存到资料库,流程为新增使用者的帐号密码後,会先判断帐号是否重复,如果帐号重复则拒绝,帐号不重复则进行密码加密流程,密码加密前先用盐(Salt)产生随机一段字串,并将盐存入资料库,然後将密码与盐组成一段字串再进行杂凑(Hash),结合处理完的密码才存到资料库,盐要分开存的原因是因为之後登入时要用来验证密码,更详细的观念可以参考下面提供的连结。
本来一开始没做加密,後来随便找了内建的 SHA256 做加密,再後来看到後端版再聊加密的事就认真看完讨论串,开始爬专有名词,也了解加盐可以增加原本密码的复杂度增加安全性,密码是先加盐再杂凑加密,不要顺序搞混很重要,而由於杂凑是不可从结果逆推回原始输入的演算法,所以输入的内容复杂度就很重要,可以降低被暴力破解的可能,这也是为什麽要密码要加盐的原因,了解後就试着跟着做做看吧!
👀 杂凑跟加密的不同参考文章 : Password Storage Cheat Sheet
👀 入门强烈推荐好文1 : 听说不能用明文存密码,那到底该怎麽存?
👀 入门强烈推荐好文2 : 密码存明码,怎麽不直接去裸奔算了?浅谈 Hash , 用杂凑保护密码
🧠 上面有提到加盐,一开始听到加盐其实搞不太懂到底在做啥,看完文章才有概念。
👹 题外话: 想查加密原理时,很常在讨论看到类似"你是真的想知道,还是你想做什麽 ?"
🧠 前面提到因为看到後端版在讨论加密,建议使用 bcrypt 或 Argon2 但後者好像更优,所以最後选择 Argon2 的来实作。
👀 实作参考资源 : How to Use Argon2 for Password Hashing in C#
👀 同上作者内文提到的必读好文 : How to Securely Store a Password
👀 Argon2 维基百科介绍 : https://en.wikipedia.org/wiki/Argon2
👀 Wikipedia 相关参考知识 : key derivation function (KDF)、Key stretching、Cryptographic hash function 、Salt (cryptography) 、BLAKE (hash function)
🦠 嗯~ 很多看不懂的东西呢~ 开始实作~
protected void OnDataBind(object sender, EventArgs e)
{
GridView1.Rows[0].Cells[6].Controls.Clear();
}
🙈 ( 这样老板就能改内容,可以删掉别人,但是不能删掉自己搂~ )
👀 GridView 资料系结选择不把密码秀出来,因为不想处理加密过的密码,减少制作时的难度。
using System.Security.Cryptography;
using System.Text;
using Konscious.Security.Cryptography;
// Argon2 加密
//产生 Salt 功能
private byte[] CreateSalt()
{
var buffer = new byte[16];
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(buffer);
return buffer;
}
// Hash 处理加盐的密码功能
private byte[] HashPassword(string password, byte[] salt)
{
var argon2 = new Argon2id(Encoding.UTF8.GetBytes(password));
//底下这些数字会影响运算时间,而且验证时要用一样的值
argon2.Salt = salt;
argon2.DegreeOfParallelism = 8; // 4 核心就设成 8
argon2.Iterations = 4; // 迭代运算次数
argon2.MemorySize = 1024 * 1024; // 1 GB
return argon2.GetBytes(16);
}
"帐号"
+"密码加盐加密後的结果"
+"盐"
protected void BtnAddAccount_Click(object sender, EventArgs e)
{
bool haveSameAccount = false;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sqlCheck = "SELECT * FROM managerData WHERE account = @account";
string sqlAdd = "INSERT INTO managerData (account, password, salt) VALUES(@account, @password, @salt)";
SqlCommand commandCheck = new SqlCommand(sqlCheck, connection);
SqlCommand commandAdd = new SqlCommand(sqlAdd, connection);
//检查有无重复帐号
commandCheck.Parameters.AddWithValue("@account", TBoxAddAccount.Text);
connection.Open();
SqlDataReader readerCountry = commandCheck.ExecuteReader();
if (readerCountry.Read()) {
haveSameAccount = true;
LabelAdd.Visible = true; //帐号重复通知
}
connection.Close();
//无重复帐号才执行加入
if (!haveSameAccount) {
//Hash 加盐加密
string password = TBoxAddPassword.Text;
var salt = CreateSalt();
string saltStr = Convert.ToBase64String(salt); //将 byte 改回字串存回资料表
var hash = HashPassword(password, salt);
string hashPassword = Convert.ToBase64String(hash);
commandAdd.Parameters.AddWithValue("@account", TBoxAddAccount.Text);
commandAdd.Parameters.AddWithValue("@password", hashPassword);
commandAdd.Parameters.AddWithValue("@salt", saltStr);
connection.Open();
commandAdd.ExecuteNonQuery();
connection.Close();
//画面渲染
GridView1.DataBind();
//清空输入栏位
TBoxAddAccount.Text = "";
TBoxAddPassword.Text = "";
LabelAdd.Visible = false;
}
}
📢 密码学的东西由於非本科,老实说看不太懂,所以只能尽量跟着参考文章进行,不过看完找到的入门强烈推荐好文,觉得懂了好多东西,有原来加盐要这样加的体悟,虽然维基百科的内容有超级多看不懂的地方,不过还是很有趣,实作的 SQL 写法也都用最简单就能做到的方式,希望大家看得懂。
>>: Indexed Element、请 TWGL 替程序码减肥
前言 快要结束了,今天要继续写 admin_bp。今天的内容会用到 JS,但我不会多加解释。 pos...
在工作中或多或少都会遇到空白行存在的情况。如果只有几个空白行,那麽手动轻松删除即可,但是遇到100行...
今天大概会聊到的范围 Constraint Layout in Compose 上一篇提到,有 R...
前面几天我们已经用 TDD 的方式完成了 <Editor /> 元件,但不要忘了 TDD...
Redis.config SIZE 注意size设定可以用以下方式,不分大小写,但k 与 kb 代表...