c#中的密码加密

现在加密技术很多,比如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进行比较以确定用户输入密码是否正确

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

public UserData GetByName(string userName, byte[] password)
{
    UserData userData;
    using (Users usersDataAccess = new Users())
    {
        userData = usersDataAccess.LoadUserByUserName(userName);
    }
    byte[] dbPassword = UserData.UserPassword;

    if (ComparePasswords(dbPassword, password))
        return userData;
    else
        return null;
}


// 比较密码
private bool ComparePasswords(byte[] storedPassword, byte[] hashedPassword)
{
    if (storedPassword == null || hashedPassword == null || hashedPassword.Length != storedPassword.Length - saltLength)
    return false;
    // 获得存储的密钥值
    byte[] saltValue = new byte[saltLength];
    int saltOffset = storedPassword.Length - saltLength;
    for (int i = 0; i < saltLength; i++)
        saltValue[i] = storedPassword[saltOffset + i];
        byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPassword);

 // 比较存贮的密码序列和计算后的密码序列
        return CompareByteArray(storedPassword, saltedPassword);
    }

private byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
{
    // 在哈希值末尾添加密钥
    byte[] rawSalted = new byte[unsaltedPassword.Length + saltValue.Length];
    unsaltedPassword.CopyTo(rawSalted, 0);
    saltValue.CopyTo(rawSalted, unsaltedPassword.Length);

    // 计算哈希值
    SHA1 sha1 = SHA1.Create();
    byte[] saltedPassword = sha1.ComputeHash(rawSalted);

    // 在哈希值末尾添加密钥
    byte[] dbPassword = new byte[saltedPassword.Length + saltValue.Length];
    saltedPassword.CopyTo(dbPassword, 0);
    saltValue.CopyTo(dbPassword, saltedPassword.Length);

    return dbPassword;
}

// 比较两个 byte 数组的内容
private bool CompareByteArray(byte[] array1, byte[] array2)
{
    if (array1.Length != array2.Length)
        return false;
    for (int i = 0; i < array1.Length; i++)
    {
        if (array1[i] != array2[i])
     return false;
    }
    return true;
}


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

    return CreateSaltedPassword(saltValue, unsaltedPassword);
}

不知道为什么弄的这么复杂

c#程序中对密码进行加密的方法

在ADO.NET中,向数据库添加数据时,怎样对数据中的密码进行加密?(也就是说在数据表中也看不到用户的密

码,只是一些经过编译后的字符串,以防止数据库管理员利用用户的密码进行非法操作。)
    首先,在c#WinForm程序中引入命名空间,"using System.Web.Security;",此命名空间是专门用来对程序进

行安全设置的;
    其次,定义一个string类型的变量,用来接收用输入的密码;
  string passWord = this.textBox1.Text.Trim();
    取到密码之后,接下来便是对密码进行加密处理:
  string pwd = FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "md5");
    最后,将加密后的密码pwd添加到数据库中去。
  insert into userInfo(uName,pwd) values('{0}','{1}');select @@identity", this.txtUID.Text.Trim

(),passwrod);
  示例代码:
  using System.Web.Security;

//取得文本框中的密码
    string pwd = this.txtPwd1.Text.Trim();
    //对密码加密
    string passwrod = FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "md5");

这个在winform里面不好用
    //创建SQL语句,将加密后的密码保存到数据库中
    string insCmd =
          string.Format("insert into userInfo(uName,pwd) values('{0}','{1}');select @@identity",

this.txtUID.Text.Trim(),passwrod);
    using (SqlCommand cmd = new SqlCommand(insCmd, Form1.Connection))
    {
        int uid = Convert.ToInt32(cmd.ExecuteScalar());
        //int uid = int.Parse(cmd.ExecuteScalar());//error
        if (uid > 0)
        {
            string mess = string.Format("恭喜,注册成功!您的号码是{0}",uid);
            MessageBox.Show(mess);
        }
        else
        {
            MessageBox.Show("对不起,注册失败了!");
        }
    }

这样加密之后保证了用户密码的安全,但是又出现了一个问题,即用户登录时怎样对密码进行验证,该不会让

用户去记住加密后的那一长串字符串吧? 答案当然是否定的,那怎样解决呢?
  应该这样解决:
  在用户登录时,得到用户输入的密码;
  然后,将取到的密码再次进行加密;
  之后,根据用户名取出该用户在数据库中的真实密码;
  最后,将刚刚进行加密的密码与数据库密码进行比对,即可完成用户登录操作。
  示例代码:
  string pwd = this.txtPwd1.Text.Trim();
                string pwd1 = FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "md5");
                string uid = this.txtUID.Text.Trim();
                string selCmd = string.Format("select pwd from userINfo where uName='{0}'", uid);
                string password = "";
                using (SqlCommand cmd = new SqlCommand(selCmd, Form1.Connection))
                {
                    password= cmd.ExecuteScalar().ToString();
               
                }
                if (password == pwd1)
                {
                    MessageBox.Show("登录成功");
                }
                else
                {
                    MessageBox.Show("密码错误!");
                }

1)使用 SHA1 生成散列

通过如下的示例代码,来演示如何通过SHA1生成散列:

byte [] bytePassword = null;

string tmpPassword = txtPassword.Text.Trim();

// 创建新的加密服务提供程序对象

SHA1 sha1 = SHA1.Create();

// 将原始字符串转换成字节数组,然后计算散列,并返回一个字节数组

bytePassword = sha1.ComputeHash(Encoding.Unicode.GetBytes(tmpPassword));

// Releases all resources used by the System.Security.Cryptography.HashAlgorithm.

sha1.Clear();

// 返回散列值的 Base64 编码字符串

txtResults.Text = Convert.ToBase64String(bytePassword);

传递不同的字符串值来调用该例程,查看散列值的变化。例如,如果将字符串Rickie传递给该例程,输出结果:

v8ocXHBvlh4EqY/2HsJNH5XBVG0=

现在,将此过程中的输入值更改为Ricky。你将看到以下输出结果:

luQsSa61sB/7PT9piDx+OAGqCnI=

如此可见,输入字符串的一个小小变化就会产生完全不同的字符组合。这正是散列算法之所以有效的原因,它使我们很难找到输入字符串的规律,也很难根据加密后的字符弄清楚字符串原来的模样。

2)使用MD5也可以生成散列

通过如下的示例代码,来演示如何通过MD5生成散列:

byte [] bytePassword = null;

string tmpPassword = txtPassword.Text.Trim();

MD5 md5 = MD5.Create();

bytePassword = md5.ComputeHash(Encoding.Unicode.GetBytes(tmpPassword));

// Releases all resources used by the System.Security.Cryptography.HashAlgorithm.

md5.Clear();

txtResults.Text = Convert.ToBase64String(bytePassword);

输入Rickie,MD5散列算法的输出结果:

YUqR1JfNxrciyG0ixNj58A==

同样,加密后的字符串看起来也与原始输入相去甚远。这些散列算法对于创建没有任何意义的密码来说非常有用,也使黑客很难猜出这些密码。之所以使用散列算法,是因为可以用这种算法对密码进行加密并将其存储在数据库中。然后,当用户输入真实密码时,需要先对用户输入的密码进行同样的散列,然后通过网络发送到数据库中,比较它与数据库中的密码是否匹配。

请记住,散列是单向操作。使用散列算法对原始密码加密后将无法再恢复。

上述两种散列算法都执行同一种操作。不同之处只在于生成散列的密钥大小以及使用的算法。使用的密钥越大,加密就越安全。例如,MD5 使用的加密密钥比 SHA1 使用的密钥大,因此 MD5 散列较难破解。

对于散列算法要考虑的另外一点是,从实践或理论的角度上看是否存在冲突的可能性。冲突是我们所不希望的,因为两个不同的单词可能会生成相同的散列。例如,SHA1 从实践或理论上来讲没有发生冲突的可能性MD5 从理论上讲有发生冲突的可能性,但从实践上讲没有发生冲突的可能性。因此,选择哪种算法归根结底取决于所需要的安全级别

[转]C#用SHA对密码加密相关推荐

  1. 用户密码加密存储十问十答,一文说透密码安全存储

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 程序员赵鑫 来源 | cnblogs.com/xinzh ...

  2. C# 使用Salt+Hash来为密码加密

    (一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到 ...

  3. 常见登录密码加密方式

    目录 1 常见的加密方式 1.1.可逆加密算法 1.1.1. 对称加密 1.1.2. 非对称加密 1.2.不可逆加密算法 1.3.Base64编码 2 密码加密的方式选型 2.1 MD5密码加密 2. ...

  4. 什么叫MD5,MD5通常做什么用处,为什么MD5不可逆,用做密码加密的时候仍然可能会被解密?

    这里是修真院后端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析后端知识/技能,本篇分享的是: [什么叫MD5, ...

  5. 数据库身份证号加密密码加密_使用密码加密数据

    数据库身份证号加密密码加密 介绍 (Introduction) When we're encrypting data, typically we will create a random key th ...

  6. 微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、JWT鉴权

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  7. 微服务网关鉴权——gateway使用、网关限流使用、用户密码加密、JWT鉴权

    文章目录 微服务网关鉴权 课程目标 1.微服务网关Gateway 1.1 微服务网关概述 1.2 微服务网关微服务搭建 1.3 微服务网关跨域 1.4 微服务网关过滤器 2 网关限流 2.1 思路分析 ...

  8. 消息摘要算法与密码加密

    在Spring Boot项目中,提供了DigestUtils工具类,此工具类的方法可以轻松实现"使用MD5算法"进行运算,从而,可以实现将原始密码进行加密,得到一个加密后的结果. ...

  9. 微服务网关鉴权:gateway使用、网关限流使用 用户密码加密 JWT鉴权

    目标 掌握微服务网关Gateway的系统搭建 掌握网关限流的实现 能够使用BCrypt实现对密码的加密与验证 了解加密算法 能够使用JWT实现微服务鉴权 1.微服务网关Gateway 1.1 微服务网 ...

  10. bcrypt java maven_BCrypt 密码加密

    1 介绍 任何应用考虑到安全,绝不能明文的方式保存密码.密码应该通过哈希算法进行加密.有很多标准的算法比 SHA 或者 MD5,结合 salt (盐)是一个不错的选择.Spring Security ...

最新文章

  1. 【黑客浅析】像黑客一样思考
  2. 【MySQL】基础知识
  3. 分配性质是什么意思_苏教版六年级数学上册3.9按比分配问题(1)微课视频 | 练习...
  4. 微信小程序教学第三章第四节(含视频):小程序中级实战教程:下拉更新、分享、阅读标识...
  5. NYOJ-99 单词拼接(欧拉+回溯)
  6. 线性表应用之线性表算法设计六大经典案例
  7. java对象在内存中的布局
  8. 【Floyed】【匈牙利算法】导弹(jzoj 1610)
  9. 我三年开发经验,从字节跳动抖音离职后,吐血整理
  10. 【hihocoder - offer编程练习赛60 B】最大顺子(双指针,思维)
  11. html 表格行排序,用客户端HTML表格排序对行进行分组
  12. php require vs. include
  13. 树和二叉树2——输出广义表形式(带括号)二叉树
  14. 大数据分析中常见的分析模型
  15. python的自省基础
  16. 算法第四版C++算法实现全集
  17. 使用paddlepaddle 进行人脸识别
  18. matlab求方差和标准差
  19. html的特殊符号五角星,五角星怎么打出来?打出五角星符号的方法
  20. 微信api接口调用-发朋友圈

热门文章

  1. Linux手动配置虚拟机网络的两种方式
  2. 【树状数组】【P3608】平衡的照片
  3. 【对讲机的那点事】安装中继台天馈系统如何制作同轴电缆BNC接头?
  4. turtle模块实现多边形
  5. OPTIMIZE TABLE的作用--转载
  6. 检查服务产生的core文件并做短信处理(shell)
  7. Ext JS4百强应用:设置textfield的悬浮提示信息 --第8强
  8. 利用路由器实现×××的基本配置方法
  9. nohup与区别于使用
  10. 系统集成Nacos和Feign