网站首页 > 技术文章 正文
过去一段时间来, 众多的网站遭遇用户密码数据库泄露事件。层出不穷的类似事件对用户会造成巨大的影响,因为人们往往习惯在不同网站使用相同的密码,一家 “暴库”,全部遭殃。
单向加密
一个简单的方案是将明文密码做单向哈希后存储。
单向哈希算法有一个特性,无法通过哈希后的摘要(digest) 恢复原始数据,这也是 “单向” 二字的来源,这一点和所有的加密算法都不同。常用的单向哈希算法包括 SHA-256, SHA-1, MD5 等。例如,对密码“passwordhunter” 进行 SHA-256 哈希后的摘要 (digest) 如下:
“bbed833d2c7805c4bf039b140bec7e7452125a04efa9e0b296395a9b95c2d44c”
可能是 “单向” 二字有误导性,也可能是上面那串数字唬人,不少人误以为这种方式很可靠, 其实不然。
单向哈希有两个特性:
1)从同一个密码进行单向哈希,得到的总是唯一确定的摘要
2)计算速度快。随着技术进步,尤其是显卡在高性能计算中的普及,一秒钟能够完成数十亿次单向哈希计算
结合上面两个特点,考虑到多数人所使用的密码为常见的组合,攻击者可以将所有密码的常见组合进行单向哈希,得到一个摘要组合, 然后与数据库中的摘要进行比对即可获得对应的密码。这个摘要组合也被称为 rainbow table(彩虹表)。
更糟糕的是,一个攻击者只要建立上述的rainbow table,可以匹配所有的密码数据库。仍然等同于一家 “暴库”,全部遭殃。
加盐哈希
将明文密码混入 “随机因素 “,然后进行单向哈希后存储,也就是所谓的”Salted Hash(加盐哈希)”。
这个方式相比上面的方案,最大的好处是针对每一个数据库中的密码,都需要建立一个完整的 rainbow table 进行匹配。 因为两个同样使用 “passwordhunter”作为密码的账户,在数据库中存储的摘要完全不同。
在 C# 中实现加盐哈希
早在2016年,MD5 作为哈希算法已经不可靠,可以人为制造碰撞,于是本文采用了 SHA256 作为哈希算法。同时在哈希前生成了一个 Guid 作为盐和哈希值拼接在一起:
using System;
using System.Security.Cryptography;
using System.Text;
public class PasswordHasher
{
public string HashPassword(string password)
{
var rnd = Guid.NewGuid().ToString("N").Substring(10);
return BuildHash(rnd, password);
}
public bool CheckPassword(string password, string hash)
{
if (string.IsNullOrWhiteSpace(hash))
{
return false;
}
var items = hash.Split('|');
if (items.Length != 2)
{
return false;
}
var rnd = items[0];
return hash == BuildHash(rnd, password);
}
private string BuildHash(string rnd, string password)
{
var key = rnd + "|" + password.Trim();
var hash = Hash(key);
return rnd + "|" + hash;
}
private string Hash(string input)
{
using (var sha = new SHA256CryptoServiceProvider())
{
var bytes = Encoding.UTF8.GetBytes(input);
bytes = sha.ComputeHash(bytes);
return Convert.ToBase64String(bytes);
}
}
}
生成加盐哈希值:
//生成加盐哈希
var hasher = new PasswordHasher();
var pwd = hasher.HashPassword("123456");
Console.WriteLine("加盐哈希值为:{0}",pwd);
校验密码是否匹配:
//校验密码是否匹配
var hasher = new PasswordHasher();
var hash = "89455bb276f037799fea1d|1rcfw+tSKhpG7zuW7Sm6SuMgjafAwsMg76OlyFkXLm8=";
var pwd = "123456";
if (hasher.CheckPassword(pwd, hash))
{
Console.WriteLine("密码正确");
}
else
{
Console.WriteLine("密码不匹配");
}
猜你喜欢
- 2024-10-03 后缀.sha或.md5文件小,用处大:防止文件被篡改,校验文件完整性
- 2024-10-03 工业级SSD的SHA算法是什么?(ssd制造)
- 2024-10-03 俄罗斯黑客在行动:Zebrocy木马家族又添新成员,Go语言了解一下
- 2024-10-03 加盐加密是什么(加盐加密是什么意思)
- 2024-10-03 浅谈编解码和加解密(编解码的基本步骤)
- 2024-10-03 md5和sha256算法的区别,哪个比较安全
- 2024-10-03 散列算法比较:MD5、SHA1、SHA256有哪些区别
- 2024-10-03 Linux 备忘录 - 13. 编解码与加解密
- 2024-10-03 SHA256算法可逆吗,SHA256算法流程步骤
- 2024-10-03 sha256为什么不可逆,sha256的安全性如何
- 10-02基于深度学习的铸件缺陷检测_如何控制和检测铸件缺陷?有缺陷铸件如何处置?
- 10-02Linux Mint 22.1 Cinnamon Edition 搭建深度学习环境
- 10-02AWD-LSTM语言模型是如何实现的_lstm语言模型
- 10-02NVIDIA Jetson Nano 2GB 系列文章(53):TAO模型训练工具简介
- 10-02使用ONNX和Torchscript加快推理速度的测试
- 10-02tensorflow GPU环境安装踩坑日记_tensorflow配置gpu环境
- 10-02Keye-VL-1.5-8B 快手 Keye-VL— 腾讯云两卡 32GB GPU保姆级部署指南
- 10-02Gateway_gateways
- 最近发表
-
- 基于深度学习的铸件缺陷检测_如何控制和检测铸件缺陷?有缺陷铸件如何处置?
- Linux Mint 22.1 Cinnamon Edition 搭建深度学习环境
- AWD-LSTM语言模型是如何实现的_lstm语言模型
- NVIDIA Jetson Nano 2GB 系列文章(53):TAO模型训练工具简介
- 使用ONNX和Torchscript加快推理速度的测试
- tensorflow GPU环境安装踩坑日记_tensorflow配置gpu环境
- Keye-VL-1.5-8B 快手 Keye-VL— 腾讯云两卡 32GB GPU保姆级部署指南
- Gateway_gateways
- Coze开源本地部署教程_开源canopen
- 扣子开源本地部署教程 丨Coze智能体小白喂饭级指南
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)