专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > CLR

DotNet加密方式解析-散列加密

发布时间:2011-06-23 13:51:12 文章来源:www.iduyao.cn 采编人员:星星草
DotNet加密方式解析--散列加密

   没时间扯淡了,赶紧上车吧。

   在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全、支付宝和微信账户安全、以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念,在这里就不说了。

   这一次将会主要讲解.NET的加密方式,接下来将会分别介绍散列加密,对称加密,非对称加密等等加密方式在.NET中的应用,本文主要讲解散列加密在.NET中的应用实例。

一.DotNet散列算法概述:

   说到散列应该都不会陌生,并且首先都会想到MD5加密,但是对于散列更加深入的了解,恐怕知道的人就不会那么多了。散列算法创建了一个散列码,也叫做“消息摘要”或“消息指纹”,看到“消息指纹”这个词,我首先想到的是可以唯一识别一个消息或者说可以唯一的标识一个人。

   1.散列算法原理概述:

 散列算法的核心是一个数学函数,在两个固定大小的数据块中运行它可以创建一个散列码。在散列算法中需要指定一个“种子值”,该值和第一块消息数据一同载入散列函数这就生成了第一个散列码,按照上一步的方式,散列码依次进入下一个散列函数运算,最后获得散列码,如下图所示:

   

   散列码是采用重复调用散列函数的链创建的,散列码依赖于消息的单个位的值。散列函数是通过操作两块固定长度的二进制数据来生成散列码,散列算法则描述类使用散列函数为消息创建散列码的过程,散列算法是使用散列函数的协议,指定类如何分解消息及如何链接之前消息快产生的结果。散列码的长度也有所限制,散列码长度较长时,需要的破解时间就会较长,这就是暴力破解的方式,但是散列码较长,生成散列码的时间就是比较长,任何策略都是需要付出代价的。

   2.DotNet的散列算法种类:

    在.NET中,常用的散列算法种类有如下几种:

    在以上列举的几种散列算法中,MD5是.NET含有的最快的散列算法。如果基础算法有缺陷,越长的散列码并不一定能够提供越好的安全。

二.DotNet散列算法应用解析:

   以上对散列算法,以及散列算法在.NET中分类做了一个简单的介绍,接下来我们具体看一下再.NET中实现这几种散列算法的类。

   在.NET中System.Security.Cryptography命名空间下的HashAlgorithm类,表示所有加密哈希算法实现均必须从中派生的基类。有如下类结构:

   在.NET中有两种类型的实现类,一个是以“Managed”结尾,这些类都被写入托管.NET语言,一种是以“CryptoServiceProvider”结尾,这些类是基于Windows CryptoAPI的。接下来我们具体的了解一下HashAlgorithm类的一些方法:

   1.HashAlgorithm类方法和属性解析:

     (1).Hash属性:获取计算所得的哈希代码的值。

public virtual byte[] Hash
    {
      get
      {
        if (this.m_bDisposed)
          throw new ObjectDisposedException((string) null);
        if (this.State != 0)
          throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_HashNotYetFinalized"));
        return (byte[]) this.HashValue.Clone();
      }
    }

  该属性返回类计算机的散列码值,该属性是一个字节数组,由代码可以看出该属性是只读的,返回计算所得的哈希代码的当前值。

     (2).Create()方法:创建哈希算法的指定实现的实例。

  public static HashAlgorithm Create(string hashName)
    {
      return (HashAlgorithm) CryptoConfig.CreateFromName(hashName);
    }

     由代码可知,指定哈希算法的新实例,如果hashName不是有效哈希算法,则为 null,该方法使用名称创建一个HashAlgorithm对象的新实例。

     (3).ComputeHash()方法:从字节数组和数据流中创建散列码。

 public byte[] ComputeHash(byte[] buffer)
    {
      if (this.m_bDisposed)
        throw new ObjectDisposedException((string) null);
      if (buffer == null)
        throw new ArgumentNullException("buffer");
      this.HashCore(buffer, 0, buffer.Length);
      this.HashValue = this.HashFinal();
      byte[] numArray = (byte[]) this.HashValue.Clone();
      this.Initialize();
      return numArray;
    }

   以上是ComputeHash()方法的一个重载版本,使用字节数组来创建一个散列码,该方法返回一个字节数组,该数组含有消息数据的散列码。HashCore()将写入对象的数据路由到哈希算法以计算哈希值,HashFinal()在加密流对象处理完最后的数据后完成哈希计算。

   2.HMAC类: 表示基于哈希的消息验证代码 (HMAC) 的所有实现必须从中派生的抽象类。

     创建加密散列码(消息验证码MACs)有两种方式:

       第一种:先合并类密钥和消息数据,再使用通常的加密散列算法来为该并集创建散列码。常用的是HMAC标准。

       第二种:使用对称算法来加密消息数据,除了最后几位之外,所有的加密数据位都将被舍弃。

   HMAC标准制定了如何合并消息数据和密钥,但是没有指定应该使用那种散列算法来创建散列码,这也就意味着该标准可以应用于任何算法。

    (1).Key属性:获取或设置用于哈希算法的密钥。

 public override byte[] Key
    {
      get
      {
        return (byte[]) this.KeyValue.Clone();
      }
      set
      {
        if (this.m_hashing)
          throw new CryptographicException(Environment.GetResourceString("Cryptography_HashKeySet"));
        this.InitializeKey(value);
      }
    }

   该属性在这里进行类重写,该属性是一个字节数组,属性可读写。

    (2).Create()方法:创建基于哈希的消息验证代码 (HMAC) 指定实现的实例。

public static HMAC Create(string algorithmName)
    {
      return (HMAC) CryptoConfig.CreateFromName(algorithmName);
    }

   该方法指定的 HMAC 实现的新实例,该方法跟HashAlgorithm类的Create方法类似,这里就不做深入的解析。

    (3).HashCore()方法:将写入对象的数据路由给默认 HMAC 哈希算法以计算哈希值。

  protected override void HashCore(byte[] rgb, int ib, int cb)
    {
      if (!this.m_hashing)
      {
        this.m_hash1.TransformBlock(this.m_inner, 0, this.m_inner.Length, this.m_inner, 0);
        this.m_hashing = true;
      }
      this.m_hash1.TransformBlock(rgb, ib, cb, rgb, ib);
    }

   该方法在这里被重写,将写入对象的数据路由给默认 HMAC 哈希算法以计算哈希值。TransformBlock()计算输入字节数组的指定区域的哈希值,将输入字节数组的指定区域复制到指定的区域,输出字节数组。

三.DotNet散列算法实现实例:

   以上介绍在.NET下的散列加密的主要类,接下来看一下MD5的具体实现代码:

  /// <summary>
  /// 表示 MD5哈希算法的所有实现均从中继承的抽象类。
  /// </summary>
  [ComVisible(true)]
  public abstract class MD5 : HashAlgorithm
  {
    /// <summary>
    /// 初始化 MD5 的新实例。
    /// </summary>
    protected MD5()
    {
      this.HashSizeValue = 128;
    }

    /// <summary>
    /// 创建MD5 哈希算法的默认实现的实例。
    /// </summary>
    /// <returns>
    /// <see cref="T:System.Security.Cryptography.MD5"/> 哈希算法的新实例。
    /// </returns>   
    public static MD5 Create()
    {
      return MD5.Create("System.Security.Cryptography.MD5");
    }

    /// <summary>
    /// 创建MD5 哈希算法的指定实现的实例。
    /// </summary> 
    /// <returns>
    public static MD5 Create(string algName)
    {
      return (MD5) CryptoConfig.CreateFromName(algName);
    }
  }

   由以上的代码可以看住,在MD5类中,具体的实现方法都是由HashAlgorithm类的Create方法实现,在这里就不再做介绍。

   1.SHA1算法实例:

   public static string GetSha1(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                throw new ArgumentNullException(str);
            }
            try
            {
                //建立SHA1对象
                SHA1 sha = new SHA1CryptoServiceProvider();
                //将mystr转换成byte[] 
                var enc = new ASCIIEncoding();
                var dataToHash = enc.GetBytes(str);
                //Hash运算
                var dataHashed = sha.ComputeHash(dataToHash);
                //将运算结果转换成string
                var hash = BitConverter.ToString(dataHashed).Replace("-", "");
                return hash;
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            catch (ArgumentException arex)
            {
                throw arex;
            }
            catch (ObjectDisposedException obex)
            {
                throw obex;
            }

   2.MD5加密实例:

  /// <summary>
        /// 32位大写
        /// </summary>
        /// <returns></returns>
        public static string Upper32(string s)
        {
            var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                s = hashPasswordForStoringInConfigFile;
            return s.ToUpper();
        }

        /// <summary>
        /// 32位小写
        /// </summary>
        /// <returns></returns>
        public static string Lower32(string s)
        {
            var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                s = hashPasswordForStoringInConfigFile;
            return s.ToLower();
        }

        /// <summary>
        /// 16位大写
        /// </summary>
        /// <returns></returns>
        public static string Upper16(string s)
        {
            var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                s = hashPasswordForStoringInConfigFile.ToString();
            return s.ToUpper().Substring(8, 16);
        }

        /// <summary>
        /// 16位小写
        /// </summary>
        /// <returns></returns>
        public static string Lower16(string s)
        {
            var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "md5");
            if (hashPasswordForStoringInConfigFile != null)
                s = hashPasswordForStoringInConfigFile.ToString();
            return s.ToLower().Substring(8, 16);
        }

四.总结:

    以上介绍了散列算法在.NET的应用和原理,希望可以帮到一些人,如果文章中有写的错误和不到位的地方,还望大家多多批评指正。

  友情添加一个加密的helper方法:http://www.cnblogs.com/liqingwen/p/6155694.html

 

加密算法系列:

       DotNet加密方式解析--散列加密:http://www.cnblogs.com/pengze0902/p/6268700.html

       DotNet加密方式解析--对称加密:http://www.cnblogs.com/pengze0902/p/6268702.html

       DotNet加密方式解析--数字签名:http://www.cnblogs.com/pengze0902/p/6268709.html

       DotNet加密方式解析--非对称加密:http://www.cnblogs.com/pengze0902/p/6268705.html

11楼学止境
楼主,错别字“对称加密,非堆成加密等等加密方式在.NET中的应用”
Re: 彭泽0902
@学止境,多谢指正啊,这就修改。。没注意
10楼付腾升
mark
Re: 彭泽0902
@付腾升,多谢支持。。。
9楼科比可祎
学习
Re: 彭泽0902
@科比可祎,相互学习。。哈哈哈。。。
8楼反骨仔(二五仔)
Re: 彭泽0902
@反骨仔(二五仔),已经修改
7楼思云
时间很近,,System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile,可还是使用过时的代码。,MD5.Create().ComputeHash(byte[])
Re: 彭泽0902
@独孤飞,欢迎引用。。。
5楼lvtu0902
mark
Re: 彭泽0902
@lvtu0902,一起来扯淡吧。。。。
4楼万归藏
MD5加密建议楼主用MD5CryptoServiceProvider.ComputeHash()方法,System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile方法在最新的MSDN文档中已经标记为:“此API现已过时”,https://msdn.microsoft.com/zh-cn/library/system.web.security.formsauthentication.hashpasswordforstoringinconfigfile(v=vs.110).aspx
Re: 彭泽0902
@万归藏,多谢建议。。。。
Re: 反骨仔(二五仔)
@万归藏,http://www.cnblogs.com/liqingwen/p/6155694.html
3楼寡妇克星
MD5不应该称为加密吧?有加密也肯定有解密,MD5不能被解密。,应该叫做签名吧?
Re: 彭泽0902
@寡妇克星,签名也是一种加密策略,其实在逻辑上是没有多大问题的一种说法。
2楼b4b4
总结到位,一次性学饱。
Re: 彭泽0902
@b4b4,哈哈哈。。后面还有。。。
1楼b4b4
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • [精粹]正则表达式30分钟入门教程(转)

    [精华]正则表达式30分钟入门教程(转) 前言   今天做东西的时候碰到个正则表达式的需求,以前做数据验证的时候因为都是一些通用的东...

  • WCF学习1

    WCF学习一 在阅读博客园 WCF开发实战系列一:创建第一个WCF服务 一文中,发现手动配置App.config还是有难度。这篇文章没讲很多...

  • .NET 类库研究必备参照 添加微软企业库源码

    .NET 类库研究必备参考 添加微软企业库源码 前不久,为大家提供了一个.NET 类库参考源码的网站,扣丁格鲁(谐音&ldquo;coding guru...

  • .NET 类库研究必备参照 扣丁格鲁

    .NET 类库研究必备参考 扣丁格鲁 .NET 类库的强大让我们很轻松的解决常见问题,作为一个好专研的程序员,为了更上一层楼,研究CLR...

  • 垃圾回收机制GC知识再总结兼谈怎么用好GC

    垃圾回收机制GC知识再总结兼谈如何用好GC 一、为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1、为对应的资源分配内...

  • .NET 4.5.1 参照源码索引

    .NET 4.5.1 参考源码索引...

  • 关于GC跟析构函数的一个趣题

    关于GC和析构函数的一个趣题 这个有趣的问题感谢装配脑袋友情提供。 请看如下代码: public class Dummy { publi...

  • 对程序集的几点懂得

    对程序集的几点理解   CLR对程序集的解释是:程序集是一个或多个类型定义文件及资源文件的集合。平时我们常见的后缀为dll或exe的...

  • 渣滓回收期算法简介

    垃圾回收期算法简介 垃圾回收器检查托管堆中是否有应用程序不再使用的对象,如果有,他们使用的内存就可以回收(如果一次垃圾回收之后...

  • CLR值类型跟引用类型

    CLR值类型和引用类型 知识点:引用类型、值类型、装箱、拆箱 CLR支持两种类型:引用类型和值类型。引用类型在堆上分配内存,值类型在线...