HASH 以及Cryptography Application Block(5)中的盐(Salt)

1.Hash介绍

Hash(比如MD5)为单向加密,这类加算法一般给你一个被加密值,就可以生成一个16字节的结果值。

MD5(12345)->827CCB0EEA8A706C4C34A16891F84E7B,

MD5(12346)->A3590023DF66AC92AE35E3316026D17D,

12345与12346只有一字之差,但是结果差别往往很大。

单向的意思给定12345那么结果必然时是827CCB0EEA8A706C4C34A16891F84E7B,而你无法通过827CCB0EEA8A706C4C34A16891F84E7B推导出原文是12345

2.Hash的一般使用

 2.1签名:

 如wow.exe文件是否被动过手脚,网站一般公布wow.exe发布时计算的出的md5,而用户通过计算自己拿到的wow.exe文件的md5来比较网站上公布的结果就可以判断文件是否正常。

2.2 保存用户密码:

  有点安全意识的程序员都不会直接在数据库中保存用户密码。 通常将用户密码计算得到的Hash值保留下来,而用户登录时将用户输入的密码计算Hash值来比较数据库中存储的值来确定密码是否输入正确。

3.关于加盐

Salt指在待加密数据前或后插入一段随机数据,如Md5(axeet12345) 中我们在12345前加入了axeet这个Salt。

上面说到Hash的一个用处是用来保存用户密码,而用户使用的密码多数相当简单,经常看到111111,123456,888888这样的密码,MD5的结果很容易就看出来,一般的暴力破解字典存储

 几万个收集的密码以及密码加密后的Md5值是很平常的。在不加盐的情况下,攻击者只要根据加密值在数据库中做查询就可以了,而加了Salt后攻击者必需逐个计算Hash(Salt+xxxx)其中xxxx指破解字典中的常用密码,当然按照目前的CPU速度,计算十来万个Md5也就个把小时,当然这里的前提是攻击者拿到了Salt.

4.一些注意点

4.1

  MD5函数是直接针对byte进行计算的,计算后是16字节,转化成16进制后是32个字符,以前的Asp一般取中间8个字符进行保存,着就是所谓的16位与32位MD5。、

4.2

  针对一段ASCII字符,使用GB2312或UTF-8编码获取的字节数组(byte[])经过MD5后,其结果是一样的,但是如果包括中文的话,那么这两个结果是不同的,因为这两个编码在表示中文时字节取值不同,原先的ASP中一般使用GB2312,而Asp.net 中使用Utf-8  以及Enterprise Lib使用Utf-16,为得到与Asp中兼容的结果需要使用如下的代码:

            byte[] hashed= Cryptographer.CreateHash("MD5", Encoding.GetEncoding("GB2312").GetBytes( "张三的密码"));
            string md5 = CryptographyUtility.GetHexStringFromBytes(hashed);

4.3

  Asp.net中的MemberShip的Salt会保存在数据表中,即结果值 是 Hash(Salt + Password),而Enterprise Lib中使用Salt时其结果值是  Salt+Hash(Salt + Password),即Hashed前16字节保留的是Salt明文,相对来说Asp.net安全点。当然一般情况下攻击者是不能获得结果值(Hashed Value),如果某个攻击者获得了Hashed也就意味着攻击者看到了数据库,这个时候Salt也就暴露了。

4.3 Enterprise Lib 中 Cryptographer.CreateHash(string,sring)返回的是Base64编码的结果字符串,需要16进制字符时需要自己进行转化,参考上面的代码。

4.4 Asp.net中的视图(ViewState)启用签名后,其生成的签名段是 Hash(ViewState+machineKey) 的结果值,machineKey可以在Web.config中指定,默认采用机器级别的machineKey.

4.5 Enterprise Lib 中HMACMD5,HMACSHA1等加密提供需要指定一个ValidateKey,这个Key的作用是计算 Hash(data+ValidateKey).

原文地址:https://www.cnblogs.com/wdfrog/p/1862948.html