[转]c# 对密码执行散列和 salt 运算方法
本文转自:http://www.cnblogs.com/CnBlogFounder/archive/2008/07/04/1235690.html
大家对密码执行散列和Salt运算一定不陌生。两个Visual Studio企业版示例都是用的这个方法来加密这个方法的。
结合示例代码,我总结了一个包含对密码进行加密,比较等静态方法的类。
使用说明:先用HashAndSalt方法对密码进行加密,然后存储到数据库中。
在用户登录时用ComparePasswords方法在对用户输入的密码和用户注册时存储在数据库中的密码进行比较,判断用户输入的密码是否正确。
Credentials.cs using System;
using System.IO;
using System.Text;
using System.Security.Cryptography; namespace BookStore.Common
{
/// <summary>
/// Credentials 的摘要说明。
/// 原理:
/// 对密码执行散列运算
/// 若要避免以明文形式存储密码,一种常见的安全做法是对密码执行散列运算。如以下代码所示,使用 System.Security.Cryptography 命名空间(它实现 60 位 SHA- 标准)对密码进行散列运算。有关更多信息,请参见 SHA 成员。
/// 对散列执行 Salt 运算
/// 虽然对密码执行散列运算的一个好的开端,但若要增加免受潜在攻击的安全性,则可以对密码散列执行 Salt 运算。Salt 就是在已执行散列运算的密码中插入的一个随机数字。这一策略有助于阻止潜在的攻击者利用预先计算的字典攻击。字典攻击是攻击者使用密钥的所有可能组合来破解密码的攻击。当您使用 Salt 值使散列运算进一步随机化后,攻击者将需要为每个 Salt 值创建一个字典,这将使攻击变得非常复杂巧本极高。
/// Salt 值随散列存储在一起,并且未经过加密。所存储的 Salt 值可以在随后用于密码验证。
/// </summary>
public class Credentials
{
private static string key = "!8%0d-F=cj>,s&"; //密钥(增加密码复杂度,好像比较多余)
private const int saltLength = ; //定义salt值的长度 /// <summary>
/// 对密码进行Hash 和 Salt
/// </summary>
/// <param name="Password">用户输入的密码</param>
/// <returns></returns>
public static byte[] HashAndSalt(string Password)
{
return CreateDbPassword(HashPassword(Password));
} /// <summary>
/// 对用户输入的密码加上密钥key后进行SHA散列
/// </summary>
/// <param name="Password">用户输入的密码</param>
/// <returns>返回 60 位 SHA- 散列后的的byte[](60位对应0个字节)</returns>
private static byte[] HashPassword( string Password )
{
//创建SHA的对象实例sha
SHA sha = SHA.Create();
//计算输入数据的哈希值
return sha.ComputeHash( Encoding.Unicode.GetBytes( Password + key ) );
} /// <summary>
/// 比较数据库中的密码和所输入的密码是否相同
/// </summary>
/// <param name="storedPassword">数据库中的密码</param>
/// <param name="Password">用户输入的密码</param>
/// <returns>true:相等/false:不等</returns>
public static bool ComparePasswords(byte[] storedPassword, string Password)
{
//首先将用户输入的密码进行Hash散列
byte[] hashedPassword = HashPassword(Password); if (storedPassword == null || hashedPassword == null || hashedPassword.Length != storedPassword.Length - saltLength)
{
return false;
} //获取数据库中的密码的salt 值,数据库中的密码的后个字节为salt 值
byte[] saltValue = new byte[saltLength];
int saltOffset = storedPassword.Length - saltLength;
for (int i = ; i < saltLength; i++){
saltValue[i] = storedPassword[saltOffset + i];
} //用户输入的密码用户输入的密码加上salt 值,进行salt
byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPassword); //比较数据库中的密码和经过salt的用户输入密码是否相等
return CompareByteArray(storedPassword, saltedPassword);
} /// <summary>
/// 比较两个ByteArray,看是否相等
/// </summary>
/// <param name="array"></param>
/// <param name="array"></param>
/// <returns>true:相等/false:不等</returns>
private static bool CompareByteArray(byte[] array, byte[] array)
{
if (array.Length != array.Length)
{
return false;
}
for (int i = ; i < array.Length; i++)
{
if (array[i] != array[i])
{
return false;
}
}
return true;
} /// <summary>
/// 对要存储的密码进行salt运算
/// </summary>
/// <param name="unsaltedPassword">没有进行过salt运算的hash散列密码</param>
/// <returns>经过salt的密码(经过salt的密码长度为:0+=,存储密码的字段为Binary())</returns>
private static byte[] CreateDbPassword(byte[] unsaltedPassword)
{
//获得 salt 值
byte[] saltValue = new byte[saltLength];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(saltValue); return CreateSaltedPassword(saltValue, unsaltedPassword);
} /// <summary>
/// 创建一个经过salt的密码
/// </summary>
/// <param name="saltValue">salt 值</param>
/// <param name="unsaltedPassword">没有进行过salt运算的hash散列密码</param>
/// <returns>经过salt的密码</returns>
private static byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
{
//将salt值数组添加到hash散列数组后拼接成rawSalted数组中
byte[] rawSalted = new byte[unsaltedPassword.Length + saltValue.Length];
unsaltedPassword.CopyTo(rawSalted,);
saltValue.CopyTo(rawSalted,unsaltedPassword.Length); //将合并后的rawSalted数组再进行SHA散列的到saltedPassword数组(长度为0字节)
SHA sha = SHA.Create();
byte[] saltedPassword = sha.ComputeHash(rawSalted); //将salt值数组在添加到saltedPassword数组后拼接成dbPassword数组(长度为字节)
byte[] dbPassword = new byte[saltedPassword.Length + saltValue.Length];
saltedPassword.CopyTo(dbPassword,);
saltValue.CopyTo(dbPassword,saltedPassword.Length); return dbPassword;
} }
}
[转]c# 对密码执行散列和 salt 运算方法的更多相关文章
- js数据结构之hash散列的详细实现方法
hash散列中需要确定key和value的唯一确定关系. hash散列便于快速的插入删除和修改,不便于查找最大值等其他操作 以下为字符和数字的hash散列: function HashTable () ...
- Flask学习记录之使用Werkzeug散列密码
数据库中直接存放明文密码是很危险的,Werkzeug库中的security能够方便的实现散列密码的计算 security库中 generate_password_hash(password,metho ...
- Shiro入门学习之散列算法与凭证配置(六)
一.散列算法概述 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5.SHA等,一般进行散列时最好提供一个salt(“盐”),什么意思?举个栗子 ...
- JDK8;HashMap:再散列解决hash冲突 ,源码分析和分析思路
JDK8中的HashMap相对JDK7中的HashMap做了些优化. 接下来先通过官方的英文注释探究新HashMap的散列怎么实现 先不给源码,因为直接看源码肯定会晕,那么我们先从简单的概念先讲起 ...
- 【数据结构与算法Python版学习笔记】查找与排序——散列、散列函数、区块链
散列 Hasing 前言 如果数据项之间是按照大小排好序的话,就可以利用二分查找来降低算法复杂度. 现在我们进一步来构造一个新的数据结构, 能使得查找算法的复杂度降到O(1), 这种概念称为" ...
- DotNet加密方式解析--散列加密
没时间扯淡类,赶紧上车吧. 在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念, ...
- .NET加密方式解析--散列加密
在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念,在这里就不说了. 这一次将会 ...
- Java 散列集笔记
散列表 散列表(hash table)为每个对象计算一个整数,称为散列码(hash code). 若需要自定义类,就要负责实现这个类的hashCode方法.注意自己实现的hashCode方法应该与eq ...
- [No0000132]正确使用密码加盐散列[译]
如果你是一个 web 开发工程师,可能你已经建立了一个用户账户系统.一个用户账户系统最重要的部分是如何保护密码.用户账户数据库经常被黑,如果你的网站曾经被攻击过,你绝对必须做点什么来保护你的用户的密码 ...
随机推荐
- MVC系统学习1—MVC执行流程
用MVC来做开发也有一段时间了,但是感觉一直没入门,就徘徊在似懂非懂的层次,和去年刚毕业学习WebForm时一样,当时通过张子阳老兄的几篇文章,明白了请求处理流程,页面生命周期才真正明白了WebFor ...
- KMP超强模板贴一份
)== ) { ); next[]=; ; ;i<=n;i++) { ]!=str[i]) j=next[j]; ...
- Linux 使用pwgen命令创建随机密码
https://blog.csdn.net/fdipzone/article/details/73864598 http://www.netkou.com/?post=155
- SiteMesh2-标签库
SiteMesh包括两大标签库. 一.Decorator Tags:被用于建立装饰器页面. 1.<decorator:head/> 插入原始页面(被包装页面)的head标签中的内容(不包 ...
- [C++] 自己主动关闭右下角弹窗
近期腾讯.迅雷等各种client,都越发喜欢在屏幕的右下角弹框了. 有骨气的人当然能够把这些软件卸载了事,可是这些client在某些情况下却又还是实用的.怎么办呢? 作为码农,自己实现一个自己主动关闭 ...
- Effective C++ Item 44 将与參数无关的代码抽离 templates
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Templates 生成多个 classes 和多个函数,所以不论什么 templat ...
- Windows Azure 故障转移模式及高可用个模式探讨!
眼下国内非常多用户对于云服务的可用性存在误解,什么样子的误解呢?比方某云服务商,在华南某地有一个机房,在华东有一个机房. 这个客户就提到一个需求,你提供的99%可用性的概念是什么意思呢?是不是我 ...
- MyEclipse 9.0 正式版公布新闻 下载
MyEclipse 9.0 正式版公布 新闻 ============================================================================ ...
- 自己动手写reg注册表文件
自己动手写reg注册表文件 2015-01-12 20:23 1161人阅读 评论(1) 收藏 举报 分类: 玩转Windows应用层编程(12) 版权声明:本文为博主原创文章,未经博主允许不得转 ...
- 项目构建之maven篇:1.环境搭建
maven下载: 下载地址 环境变量设置 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd29iZW5kaWFua3Vu/font/5a6L5L2T/fon ...