[转]C#用SHA对密码加密

原文地址: http://ainux.blog.hexun.com/2815875_d.html


现在加密技术很多,比如SHA,MD5(已经被破解了),小可想和大家讨论一下在.NET框架中简单应用SHA算法加密用户登录密码的方法。
这里我采用的是SHA1(安全散列算法),是将不定长的字符串转换成160位(20字节)字节流散列算法。
这里讲的加密一般分以下几个步骤:

密码的建立:
1)对用户的原始密码进行第一次哈希,得到UnsaltedPassword:
User password ====hash====> UnsaltedPassword (20B)
2)随机产生一个N字节的密钥值(salt value),拼接到上面哈希后的字节流后面即
UnsaltedPassword(20B) | Salt value(NB)
3)将以上(20 + N)Byte的字节流再经过一次哈希,得到SaltedPassword
UnsaltedPassword(20B) | Salt value(NB) ====hash====> SaltedPassword
4)将SaltedPassword(20B) | Salt value(NB)存入数据库

密码的验证:
1)从数据库中获得加密后用户密码 dbPassword,取其最后N字节作为Salt value
2)重复上面1) 3) 4)将用户输入的密码结合Salt value进行哈希加密,和dbPassword进行比较以确定用户输入密码是否正确


 

None.gif private   void  btnLogon_Click( object  sender, EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//创建SHA1类的实例,SHA1是抽象类(abstract)所以不能直接实例化
InBlock.gif
    SHA1 sha1 = SHA1.Create(); 
InBlock.gif    
//Unicode.GetBytes获得string的Unicode(双字节字符)字节流
InBlock.gif
    byte[] hashedPassword = sha1.ComputeHash(Encoding.Unicode.GetBytes(txtPassword.Text));
InBlock.gif    
//UserDate 可以理解为用户信息的抽象
InBlock.gif
    UserData user = userSystem.GetByName(txtUsername.Text, hashedPassword);
InBlock.gif    
if (user == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//登录失败处理
ExpandedSubBlockEnd.gif
    }

ExpandedBlockEnd.gif}

None.gif
None.gif
public  UserData GetByName( string  userName,  byte [] password)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    UserData userData;
InBlock.gif    
using (Users usersDataAccess = new Users())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        userData 
= usersDataAccess.LoadUserByUserName(userName);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
byte[] dbPassword = UserData.UserPassword;
InBlock.gif
InBlock.gif    
if (ComparePasswords(dbPassword, password))
InBlock.gif        
return userData;
InBlock.gif    
else
InBlock.gif        
return null;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
//  比较密码
None.gif
private   bool  ComparePasswords( byte [] storedPassword,  byte [] hashedPassword)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (storedPassword == null || hashedPassword == null || hashedPassword.Length != storedPassword.Length - saltLength)
InBlock.gif    
return false;
InBlock.gif    
// 获得存储的密钥值
InBlock.gif
    byte[] saltValue = new byte[saltLength];
InBlock.gif    
int saltOffset = storedPassword.Length - saltLength;
InBlock.gif    
for (int i = 0; i < saltLength; i++)
InBlock.gif        saltValue[i] 
= storedPassword[saltOffset + i];
InBlock.gif        
byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPassword);
InBlock.gif
InBlock.gif 
// 比较存贮的密码序列和计算后的密码序列
InBlock.gif
        return CompareByteArray(storedPassword, saltedPassword);
ExpandedBlockEnd.gif    }

None.gif
None.gif
private   byte [] CreateSaltedPassword( byte [] saltValue,  byte [] unsaltedPassword)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// 在哈希值末尾添加密钥
InBlock.gif
    byte[] rawSalted = new byte[unsaltedPassword.Length + saltValue.Length];
InBlock.gif    unsaltedPassword.CopyTo(rawSalted, 
0);
InBlock.gif    saltValue.CopyTo(rawSalted, unsaltedPassword.Length);
InBlock.gif
InBlock.gif    
// 计算哈希值
InBlock.gif
    SHA1 sha1 = SHA1.Create();
InBlock.gif    
byte[] saltedPassword = sha1.ComputeHash(rawSalted);
InBlock.gif
InBlock.gif    
// 在哈希值末尾添加密钥
InBlock.gif
    byte[] dbPassword = new byte[saltedPassword.Length + saltValue.Length];
InBlock.gif    saltedPassword.CopyTo(dbPassword, 
0);
InBlock.gif    saltValue.CopyTo(dbPassword, saltedPassword.Length);
InBlock.gif
InBlock.gif    
return dbPassword;
ExpandedBlockEnd.gif}

None.gif
None.gif
//  比较两个 byte 数组的内容
None.gif
private   bool  CompareByteArray( byte [] array1,  byte [] array2)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (array1.Length != array2.Length)
InBlock.gif        
return false;
InBlock.gif    
for (int i = 0; i < array1.Length; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
if (array1[i] != array2[i])
InBlock.gif     
return false;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return true;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
//  创建在数据库中存储的的哈希值(转入参数为经过一次哈希的用户输入密码的字节流)
None.gif
public   byte [] CreateDbPassword( byte [] unsaltedPassword)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
//Create a salt value
InBlock.gif
    byte[] saltValue = new byte[saltLength];
InBlock.gif    RNGCryptoServiceProvider rng 
= new RNGCryptoServiceProvider();
InBlock.gif    rng.GetBytes(saltValue);
InBlock.gif
InBlock.gif    
return CreateSaltedPassword(saltValue, unsaltedPassword);
ExpandedBlockEnd.gif}

None.gif
None.gif

转载于:https://www.cnblogs.com/asdling/archive/2006/07/05/443045.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值