转自:哈希(Hash)与加密(Encrypt)的基本原理、区别及工程应用

0、摘要

今天看到吉日嘎拉一篇关于管理软件中信息加密和安全的文章,感觉非常有实际意义。文中作者从实践经验出发,讨论了信息管理软件中如何通过哈希和加密进行数据保护。但是从文章评论中也可以看出很多朋友对这个方面一些基本概念比较模糊,这样就容易“照葫芦画瓢”,不能根据自身具体情况灵活选择和使用各种哈希和加密方式。本文不对哈希和加密做过于深入的讨论,而是对哈希和加密的基本概念和原理进行阐述、比较,并结合具体实践说明如何选择哈希和加密算法、如何提高安全性等问题,使朋友们做到“知其然,知其所以然”,这样就能通过分析具体情况,灵活运用哈希和加密保护数据。

1、哈希(Hash)与加密(Encrypt)的区别

在本文开始,我需要首先从直观层面阐述哈希(Hash)加密(Encrypt)的区别,因为我见过很多朋友对这两个概念不是很清晰,容易混淆两者。而正确区别两者是正确选择和使用哈希与加密的基础。

概括来说,哈希(Hash)是将目标文本转换成具有相同长度的、不可逆的杂凑字符串(或叫做消息摘要),而加密(Encrypt)是将目标文本转换成具有不同长度的、可逆的密文。

具体来说,两者有如下重要区别:

1、哈希算法往往被设计成生成具有相同长度的文本,而加密算法生成的文本长度与明文本身的长度有关。

例如,设我们有两段文本:“Microsoft”和“Google”。两者使用某种哈希算法得到的结果分别为:“140864078AECA1C7C35B4BEB33C53C34”和“8B36E9207C24C76E6719268E49201D94”,而使用某种加密算法的到的结果分别为“Njdsptpgu”和“Hpphmf”。可以看到,哈希的结果具有相同的长度,而加密的结果则长度不同。实际上,如果使用相同的哈希算法,不论你的输入有多么长,得到的结果长度是一个常数,而加密算法往往与明文的长度成正比。

2、哈希算法是不可逆的,而加密算法是可逆的。

这里的不可逆有两层含义,一是“给定一个哈希结果R,没有方法将E转换成原目标文本S”,二是“给定哈希结果R,即使知道一段文本S的哈希结果为R,也不能断言当初的目标文本就是S”。其实稍微想想就知道,哈希是不可能可逆的,因为如果可逆,那么哈希就是世界上最强悍的压缩方式了——能将任意大小的文件压缩成固定大小。

加密则不同,给定加密后的密文R,存在一种方法可以将R确定的转换为加密前的明文S。

这里先从直观层面简单介绍两者的区别,等下文从数学角度对两者做严谨描述后,读者朋友就知道为什么会有这两个区别了。

2、哈希(Hash)与加密(Encrypt)的数学基础

从数学角度讲,哈希和加密都是一个映射。下面正式定义两者:

      一个哈希算法是一个多对一映射,给定目标文本S,H可以将其唯一映射为R,并且对于所有S,R具有相同的长度。由于是多对一映射,所以H不存在逆映射

使得R转换为唯一的S。

      一个加密算法是一个一一映射,其中第二个参数叫做加密密钥,E可以将给定的明文S结合加密密钥Ke唯一映射为密文R,并且存在另一个一一映射,可以结合Kd将密文R唯一映射为对应明文S,其中Kd叫做解密密钥。

下图是哈希和加密过程的图示:

有了以上定义,就很清楚为什么会存在上文提到的两个区别了。由于哈希算法的定义域是一个无限集合,而值域是一个有限集合,将无限集合映射到有限集合,根据“鸽笼原理(Pigeonhole principle)”,每个哈希结果都存在无数个可能的目标文本,因此哈希不是一一映射,是不可逆的。

而加密算法是一一映射,因此理论上来说是可逆的。

但是,符合上面两个定义的映射仅仅可以被叫做哈希算法和加密算法,但未必是好的哈希和加密,好的哈希和加密往往需要一些附加条件,下面介绍这些内容。

一个设计良好的哈希算法应该很难从哈希结果找到哈希目标文本的碰撞(Collision)。那么什么是碰撞呢?对于一个哈希算法H,如果,则S1和S2互为碰撞。关于为什么好的哈希需要难以寻找碰撞,在下面讲应用的时候会详解。另外,好的哈希算法应该对于输入的改变极其敏感,即使输入有很小的改动,如一亿个字符变了一个字符,那么结果应该截然不同。这就是为什么哈希可以用来检测软件的完整性。

一个设计良好的加密算法应该是一个“单向陷门函数(Trapdoor one-way function)”,单向陷门函数的特点是一般情况下即使知道函数本身也很难将函数的值转换回函数的自变量,具体到加密也就是说很难从密文得到明文,虽然从理论上这是可行的,而“陷门”是一个特殊的元素,一旦知道了陷门,则这种逆转换则非常容易进行,具体到加密算法,陷门就是密钥。

顺便提一句,在加密中,应该保密的仅仅是明文和密钥。也就是说我们通常假设攻击者对加密算法和密文了如指掌,因此加密的安全性应该仅仅依赖于密钥而不是依赖于假设攻击者不知道加密算法。

3、哈希(Hash)与加密(Encrypt)在软件开发中的应用

哈希与加密在现代工程领域应用非常广泛,在计算机领域也发挥了很大作用,这里我们仅仅讨论在平常的软件开发中最常见的应用——数据保护。

所谓数据保护,是指在数据库被非法访问的情况下,保护敏感数据不被非法访问者直接获取。这是非常有现实意义的,试想一个公司的安保系统数据库服务器被入侵,入侵者获得了所有数据库数据的查看权限,如果管理员的口令(Password)被明文保存在数据库中,则入侵者可以进入安保系统,将整个公司的安保设施关闭,或者删除安保系统中所有的信息,这是非常严重的后果。但是,如果口令经过良好的哈希或加密,使得入侵者无法获得口令明文,那么最多的损失只是被入侵者看到了数据库中的数据,而入侵者无法使用管理员身份进入安保系统作恶。

3.1、哈希(Hash)与加密(Encrypt)的选择

要实现上述的数据保护,可以选择使用哈希或加密两种方式。那么在什么时候该选择哈希、什么时候该选择加密呢?

基本原则是:如果被保护数据仅仅用作比较验证,在以后不需要还原成明文形式,则使用哈希;如果被保护数据在以后需要被还原成明文,则需要使用加密。

例如,你正在做一个系统,你打算当用户忘记自己的登录口令时,重置此用户口令为一个随机口令,而后将此随机口令发给用户,让用户下次使用此口令登录,则适合使用哈希。实际上很多网站都是这么做的,想想你以前登录过的很多网站,是不是当你忘记口令的时候,网站并不是将你忘记的口令发送给你,而是发送给你一个新的、随机的口令,然后让你用这个新口令登录。这是因为你在注册时输入的口令被哈希后存储在数据库里,而哈希算法不可逆,所以即使是网站管理员也不可能通过哈希结果复原你的口令,而只能重置口令。

相反,如果你做的系统要求在用户忘记口令的时候必须将原口令发送给用户,而不是重置其口令,则必须选择加密而不是哈希。

完整文档参考:

哈希(Hash)与加密(Encrypt)的基本原理、区别及工程应用

hash和encrypt区别及应用_转的更多相关文章

  1. mysql索引(btree索引和hash索引的区别)

    所有MySQL列类型可以被索引.根据存储引擎定义每个表的最大索引数和最大索引长度.所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节.大多数存储引擎有更高的限制. 索引的存储类型目前只有 ...

  2. 索引原理-btree索引与hash索引的区别

    btree索引与hash索引的区别,之前不清楚,mark一下. Hash索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree索引需要从根节点到枝节点,最后才能访问到页节点这样多 ...

  3. MySQL的B+树索引和hash索引的区别

    简述一下索引: 索引是数据库表中一列或多列的值进行排序的一种数据结构:索引分为聚集索引和非聚集索引,聚集索引查询类似书的目录,快速定位查找的数据,非聚集索引查询一般需要再次回表查询一次,如果不使用索引 ...

  4. hash与encrypt

    概括来说,哈希(Hash)是将目标文本转换成具有相同长度的.不可逆的杂凑字符串(或叫做消息摘要),而加密(Encrypt)是将目标文本转换成具有不同长度的.可逆的密文. 具体来说,两者有如下重要区别: ...

  5. MySQL的btree索引和hash索引的区别

    Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...

  6. webpack中hash与chunkhash区别和需要注意的问题

    项目发布时,为了解决缓存,需要进行md5签名,这时候就需要用到 hash 和 chunkhash等. 问题一:hash问题 使用 hash 对js和css进行签名时,每一次hash值都不一样,导致无法 ...

  7. MySQL的btree索引和hash索引的区别 (转)

    Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...

  8. BTREE索引和HASH索引的区别

    从本质上理解,BTREE是一种有序树,而hash是无序的.所以最关键的区别在于: 1,BTREE可以用来做范围查询,比如大于,小于,而HASH索引仅在"=","IN&qu ...

  9. HashMap、Hashtable、HashSet三种hash集合的区别

    转载:http://www.cnblogs.com/lzrabbit/p/3721067.html#h1 HashMap和Hashtable的区别 两者最主要的区别在于Hashtable是线程安全,而 ...

随机推荐

  1. 网络编程-tcp

    一.简单的demo (1)客户端 package com.songyan.tcp; import java.io.IOException; import java.io.InputStream; im ...

  2. GAILS里面的SAVE方法

    用途 保存一个domain类的实例到数据库,需要的话会级联保存所有的子实例. 举例 def b = new Book(title:"The Shining") b.save() 描 ...

  3. Android中将Bitmap转换成单色的Bmp图片

    添加权限 :

  4. 两道Java面试题!

    body { font-family: 微软雅黑; font-size: 14px; line-height: 2; } html, body { color: inherit; background ...

  5. Quartz 2.3 动态添加、修改和删除定时任务

    下面直接上代码: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>qu ...

  6. android 电话薄先10位匹配,若是无法匹配,则换成7位匹配

    案例 1: 假设您保存的有:A:04165191666. B:5191666.  来电号码是:04165191666   由于是7位匹配,所以A和B都能够匹配到.可是最佳匹配还是A,最后显示A: 来电 ...

  7. “DllRegisterServer的调用失败”问题解决办法(转)

    在日常的工作中,用regsvr32 命令注册dll组件是,会碰到模块"xxx.dll"已加载,但DllRegisterServer的调用失败.特别是再在xp的系统上能正确注册,但是 ...

  8. nginx+vue实例纪录

    参考:http://www.cnblogs.com/wuac/p/6406843.html 新建工作目录vuepro,命令行之行命令:vue init webpack vue-test (项目默认的名 ...

  9. ETL技术入门之ETL初认识

    ETL是什么 ETL是Extract Transform Load三个英文单词的缩写 中文意思就是抽取.转换.载入.说到ETL就必须提到数据仓库. 先说下背景知识: 信息是现代企业的重要资源,是企业运 ...

  10. Java中Vector与ArrayList的差别具体解释

    首先看这两类都实现List接口,而List接口一共同拥有三个实现类.各自是ArrayList.Vector和LinkedList.List用于存放多个元素,可以维护元素的次序,而且同意元素的反复. 3 ...