vivo智能手机官网X20Plus与vivo智能手机官网 X 9 相比哪个更适合女生用?

zengzhaozheng 的BLOG
用户名:zengzhaozheng
文章数:34
评论数:27
访问量:77606
注册日期:
阅读量:5863
阅读量:12276
阅读量:416880
阅读量:1104373
51CTO推荐博文
一、概述 & &本文将粗略讲述一下Hash算法的概念特性,里边会结合分布式系统负载均衡实例对Hash的一致性做深入探讨。另外,探讨一下Hash算法在海量数据处理方案中的通用性。最后,从源代码出发,具体分析一下Hash算法在MapReduce框架的中的应用。二、Hash算法 & &Hash可以通过散列函数将任意长度的输入变成固定长度的输出,也可以将不同的输入映射成为相同的相同的输出,而且这些输出范围也是可控制的,所以起到了很好的压缩映射和等价映射功能。这些特性被应用到了信息安全领域中加密算法,其中等价映射这一特性在海量数据解决方案中起到相当大的作用,特别是在整个MapReduce框架中,下面章节会对这二方面详细说。话说,Hash为什么会有这种压缩映射和等价映射功能,主要是因为Hash函数在实现上都使用到了取模。下面看看几种常用的Hash函数:?直接取余法:f(x):= x mod maxM ; maxM一般是不太接近 2^t 的一个质数。?乘法取整法:f(x):=trunc((x/maxX)*maxlongit) mod maxM,主要用于实数。?平方取中法:f(x):=(x*x div 1000 ) mod 1000000); 平方后取中间的,每位包含信息比较多。三、Hash算法在海量数据处理方案中的应用单机处理海量数据的大体主流思想是和MapReduce框架一样,都是采取分而治之的方法,将海量数据切分为若干小份来进行处理,并且在处理的过程中要兼顾内存的使用情况和处理并发量情况。而更加仔细的处理流程大体上分为几步(对大多数情况都使用,其中少部分情况要根据你自己的实际情况和其他解决方法做比较采用最符合实际的方法):第一步:分而治之。 & &采用Hash取模进行等价映射。采用这种方法可以将巨大的文件进行等价分割(注意:符合一定规律的数据要被分割到同一个小文件)变成若干个小文件再进行处理。这个方法针对数据量巨大,内存受到限制时十分有效。第二步:利用hashMap在内存中进行统计。 & &我们通过Hash映射将大文件分割为小文件后,就可以采用HashMap这样的存储结构来对小文件中的关注项进行频率统计。具体的做法是将要进行统计的Item作为HashMap的key,此Item出现的次数作为value。第三步:在上一步进行统计完毕之后根据场景需求往往需要对存储在HashMap中的数据根据出现的次数来进行排序。其中排序我们可以采用堆排序、快速排序、归并排序等方法。 & &现在我们来看看具体的例子:【例子1】海量日志数据,提取出某日访问百度次数最多的那个IP & &思路:当看到这样的业务场景,我们脑子里应该立马会想到这些海量网关日志数据量有多大?这些IP有多少中组合情况,最大情况下占多少存储空间?解决这样的问题前我们最重要的先要知道数据的规模,这样才能从大体上制定解决方案。所以现在假设这些这些网关日志量有3T。下面大体按照我们上面的步骤来对解决此场景进行分析:(1)首先,从这些海量数据中过滤出指定一天访问百度的用户IP,并逐个写到一个大文件中。(2)采用“分而治之”的思想用Hash映射将大文件进行分割降低数据规模。按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中,其中Hash函数得出值为分割后小文件的编号。(3)逐个读小文件,对于每一个小文件构建一个IP为key,出现次数为value的HashMap。对于怎么利用HashMap记录IP出现的次数这个比较简单,因为我们可以通过程序读小文件将IP放到HashMap中key的之后可以先判断此IP是否已经存在如果不存在直接放进去,其出现次数记录为1,如果此IP已经存储则过得其对应的value值也就是出现的次数然后加1就ok。最后,按照IP出现的次数采用排序算法对HashMap中的数据进行排序,同时记录当前出现次数最多的那个IP地址;(4)走到这步,我们可以得到1024个小文件中出现次数最多的IP了,再采用常规的排序算法找出总体上出现次数最多的IP就ok了。这个我们需要特别地明确知道一下几点内容:第一:我们通过Hash函数:Hash(IP)%1024将大文件映射分割为了1024个小文件,那么这1024个小文件的大小是否均匀?另外,我们采用HashMap来进行IP频率的统计,内存消耗是否合适?首先是第一个问题,被分割的小文件的大小的均匀程度是取决于我们使用怎么样的Hash函数,对本场景而言就是:Hash(IP)%1024。设计良好的Hash函数可以减少冲突,使数据均匀的分割到1024个小文件中。但是尽管数据映射到了另外一些不同的位置,但数据还是原来的数据,只是代替和表示这些原始数据的形式发生了变化而已。另外,看看第二个问题:用HashMap统计IP出现频率的内存使用情况。要想知道HashMap在统计IP出现的频率,那么我们必须对IP组合的情况有所了解。32Bit的IP最多可以有2^32种的组合方式,也就是说去所有IP最多占4G存储空间。在此场景中,我们已经根据IP的hash值将大文件分割出了1024个小文件,也就是说这4G的IP已经被分散到了1024个文件中。那么在Hash函数设计合理最perfect的情况下针对每个小文件的HashMap占的内存大小最多为4G/1024+存储IP对应的次数所占的空间,所以内存绝对够用。第二:Hash取模是一种等价映射,换句话说通过映射分割之后相同的元素只会分到同一个小文件中去的。就本场景而言,相同的IP通过Hash函数后只会被分割到这1024个小文件中的其中一个文件。【例子2】给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url? & &思路:还是老一套,先Hash映射降低数据规模,然后统计排序。 &具体做法:(1)分析现有数据的规模。 & &按照每个url64字节来算,每个文件有50亿个url,那么每个文件大小为5G*64=320G。320G远远超出内存限定的4G,所以不能将其全部加载到内存中来进行处理,需要采用分而治之的方法进行处理。(2)Hash映射分割文件。逐行读取文件a,采用hash函数:Hash(url)%1000将url分割到1000个小文件中,文件即为f1_1,f1_2,f1_3,...,f1_1000。那么理想情况下每个小文件的大小大约为300m左右。再以相同的方法对大文件b进行相同的操作再得到1000个小文件,记为:f2_1,f2_2,f2_3,...,f2_1000。 & &经过一番折腾后我们将大文件进行了分割并且将相同url都分割到了这2组小文件中下标相同的两个文件中,其实我们可以将这2组文件看成一个整体:f1_1&f2_1,f1_2&,f2_2,f1_3&f2_3,...,f1_0。那么我们就可以将问题转化成为求这1000对小文件中相同的url就可以了。接下来,求每对小文件中的相同url,首先将每对对小文件中较小的那个的url放到HashSet结构中,然后遍历对应这对小文件中的另一个文件,看其是否存才刚刚构建的HashSet中,如果存在说明是一样的url,将这url直接存到结果文件就ok了。【例子3】有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。【例子4】有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。像例子3和例子4这些场景都可以用我们的一贯老招数解决:先Hash映射降低数据规模,然后统计加载到内存,最后排序。具体做法可以参考上面2个例子。四、Hash算法在MapReduce框架中的应用&&&&Hash算法在分布式计算框架MapReduce中起着核心作用。先来看看下面整个mapreduce的运行流程,首先是原始数据经过切片进入到map函数中,经过map函数的数据会在整个环形缓冲区里边进行第一次排序,接着map的输出结果会根据key值(默认情况是这样,另外可以自定义)进行Hash映射将数据量庞大的map输出分割为N份(N为reduce数目)来实现数据的并行处理,这就是Partition阶段,另外MapReduce框架中Partition的实现方式往往能够决定数据的倾斜度,所以在处理数据前最好要对数据的分布情况有所了解。接下来从MapReudce的源码角度来研究一下Partition的实现原理: & &其Partition的实现主要有:HashPartitioner、BinaryPartitioner、KeyFieldBasedPartitioner、TotalOrderPartitioner这几种,其中HashPartitioner是默认的。首先来看看HashPartitioner的核心实现:/**
&*&Licensed&to&the&Apache&Software&Foundation&(ASF)&under&one
&*&or&more&contributor&license&agreements.&&See&the&NOTICE&file
&*&distributed&with&this&work&for&additional&information
&*&regarding&copyright&ownership.&&The&ASF&licenses&this&file
&*&to&you&under&the&Apache&License,&Version&2.0&(the
&*&"License");&you&may&not&use&this&file&except&in&compliance
&*&with&the&License.&&You&may&obtain&a&copy&of&the&License&at
&*&&&&&http://www.apache.org/licenses/LICENSE-2.0
&*&Unless&required&by&applicable&law&or&agreed&to&in&writing,&software
&*&distributed&under&the&License&is&distributed&on&an&"AS&IS"&BASIS,
&*&WITHOUT&WARRANTIES&OR&CONDITIONS&OF&ANY&KIND,&either&express&or&implied.
&*&See&the&License&for&the&specific&language&governing&permissions&and
&*&limitations&under&the&License.
package&org.apache.hadoop.mapreduce.lib.
import&org.apache.hadoop.mapreduce.P
/**&Partition&keys&by&their&{@link&Object#hashCode()}.&*/
public&class&HashPartitioner&K,&V&&extends&Partitioner&K,&V&&{
&&/**&Use&{@link&Object#hashCode()}&to&partition.&*/
&&public&int&getPartition(K&key,&V&value,
&&&&&&&&&&&&&&&&&&&&&&&&&&int&numReduceTasks)&{
&&&&return&(key.hashCode()&&&Integer.MAX_VALUE)&%&numReduceT
}我们看到第25行,在这里我们有看到了可爱的Hash取模映射方法,这样做的原因大家看到这里都应该已经了然于心了。另外,TotalOrderPartitioner、BinaryPartitioner等几种Partitioner的实现都是基于Hash取模映射方法,只是他们为了实现自己自定义的功能而添加了一些逻辑,例如其中的TotalOrderPartitioner可以实现全排序功能。其他几个Partition的源代码这里就不贴了,有兴趣的可以自己看看。五、Hash算法的一致性本部分为本文最后一部分,之所以要介绍这一部分的内容主要是从Hash算法的完整性出发的,这部分的内容和海量数据的解决方案关系不大,主要是用于分布式缓存设计方面。由于关于这部分的内容已经有一些大拿们做了很深入的研究并且讲解地相当完美,小弟这里就直接引用了。所以本部分引用的blog。consistent hashing算法早在1997年就在论文中被提出,目前在cache系统中应用越来越广泛;1 基本场景比如你有N个cache服务器(后面简称cache),那么如何将一个对象object映射到N个cache上呢,你很可能会采用类似下面的通用方法计算object的hash值,然后均匀的映射到到N个cache;hash(object)%N一切都运行正常,再考虑如下的两种情况;1 一个cache服务器m down掉了(在实际应用中必须要考虑这种情况),这样所有映射到cache m的对象都会失效,怎么办,需要把cache m从cache中移除,这时候cache是N-1台,映射公式变成了hash(object)%(N-1);2 由于访问加重,需要添加cache,这时候cache是N+1台,映射公式变成了hash(object)%(N+1);1和2意味着什么?这意味着突然之间几乎所有的cache都失效了。对于服务器而言,这是一场灾难,洪水般的访问都会直接冲向后台服务器;再来考虑第三个问题,由于硬件能力越来越强,你可能想让后面添加的节点多做点活,显然上面的hash算法也做不到。有什么方法可以改变这个状况呢,这就是consistent hashing...2 hash 算法和单调性Hash算法的一个衡量指标是单调性(Monotonicity),定义如下:  单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。容易看到,上面的简单hash算法hash(object)%N难以满足单调性要求。3 consistent hashing 算法的原理consistent hashing是一种hash算法,简单的说,在移除/添加一个cache时,它能够尽可能小的改变已存在key映射关系,尽可能的满足单调性的要求。下面就来按照5个步骤简单讲讲consistent hashing算法的基本原理。3.1 环形hash 空间考虑通常的hash算法都是将value映射到一个32为的key值,也即是0~2^32-1次方的数值空间;我们可以将这个空间想象成一个首(0)尾(2^32-1)相接的圆环,如下面图1所示的那样。650) this.width=650;" src="/KB/recipes/lib-conhash/circle.JPG" alt="circle space" width="91" height="104" style="border:0" />图1环形hash空间3.2 把对象映射到hash 空间接下来考虑4个对象object1~object4,通过hash函数计算出的hash值key在环上的分布如图2所示。hash(object1) = key1;… …hash(object4) = key4;650) this.width=650;" src="/KB/recipes/lib-conhash/object.JPG" alt="object" width="234" height="253" style="border:0" />图2 4个对象的key值分布3.3 把cache 映射到hash 空间Consistent hashing的基本思想就是将对象和cache都映射到同一个hash数值空间中,并且使用相同的hash算法。假设当前有A,B和C共3台cache,那么其映射结果将如图3所示,他们在hash空间中,以对应的hash值排列。hash(cache A) = key A;… …hash(cache C) = key C;650) this.width=650;" src="/KB/recipes/lib-conhash/cache.JPG" alt="cache" width="283" height="253" style="border:0" />图3 cache和对象的key值分布说到这里,顺便提一下cache的hash计算,一般的方法可以使用cache机器的IP地址或者机器名作为hash输入。3.4 把对象映射到cache现在cache和对象都已经通过同一个hash算法映射到hash数值空间中了,接下来要考虑的就是如何将对象映射到cache上面了。在这个环形空间中,如果沿着顺时针方向从对象的key值出发,直到遇见一个cache,那么就将该对象存储在这个cache上,因为对象和cache的hash值是固定的,因此这个cache必然是唯一和确定的。这样不就找到了对象和cache的映射方法了吗?!依然继续上面的例子(参见图3),那么根据上面的方法,对象object1将被存储到cache A上;object2和object3对应到cache C;object4对应到cache B;3.5 考察cache 的变动前面讲过,通过hash然后求余的方法带来的最大问题就在于不能满足单调性,当cache有所变动时,cache会失效,进而对后台服务器造成巨大的冲击,现在就来分析分析consistent hashing算法。3.5.1 移除cache考虑假设cache B挂掉了,根据上面讲到的映射方法,这时受影响的将仅是那些沿cache B逆时针遍历直到下一个cache(cache C)之间的对象,也即是本来映射到cache B上的那些对象。因此这里仅需要变动对象object4,将其重新映射到cache C上即可;参见图4。650) this.width=650;" src="/KB/recipes/lib-conhash/remove.JPG" alt="remove" width="283" height="253" style="border:0" />图4 Cache B被移除后的cache映射3.5.2 添加cache再考虑添加一台新的cache D的情况,假设在这个环形hash空间中,cache D被映射在对象object2和object3之间。这时受影响的将仅是那些沿cache D逆时针遍历直到下一个cache(cache B)之间的对象(它们是也本来映射到cache C上对象的一部分),将这些对象重新映射到cache D上即可。因此这里仅需要变动对象object2,将其重新映射到cache D上;参见图5。650) this.width=650;" src="/KB/recipes/lib-conhash/add.JPG" alt="add" width="283" height="253" style="border:0" />图5 添加cache D后的映射关系4 虚拟节点考量Hash算法的另一个指标是平衡性(Balance),定义如下:平衡性  平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。hash算法并不是保证绝对的平衡,如果cache较少的话,对象并不能被均匀的映射到cache上,比如在上面的例子中,仅部署cache A和cache C的情况下,在4个对象中,cache A仅存储了object1,而cache C则存储了object2、object3和object4;分布是很不均衡的。为了解决这种情况,consistent hashing引入了“虚拟节点”的概念,它可以如下定义:“虚拟节点”(virtual node)是实际节点在hash空间的复制品(replica),一实际个节点对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在hash空间中以hash值排列。仍以仅部署cache A和cache C的情况为例,在图4中我们已经看到,cache分布并不均匀。现在我们引入虚拟节点,并设置“复制个数”为2,这就意味着一共会存在4个“虚拟节点”,cache A1, cache A2代表了cache A;cache C1, cache C2代表了cache C;假设一种比较理想的情况,参见图6。650) this.width=650;" src="/KB/recipes/lib-conhash/virtual.JPG" alt="virtual nodes" width="283" height="253" style="border:0" />图6 引入“虚拟节点”后的映射关系此时,对象到“虚拟节点”的映射关系为:objec1-&cache A2;objec2-&cache A1;objec3-&cache C1;objec4-&cache C2;因此对象object1和object2都被映射到了cache A上,而object3和object4映射到了cache C上;平衡性有了很大提高。引入“虚拟节点”后,映射关系就从{对象-&节点}转换到了{对象-&虚拟节点}。查询物体所在cache时的映射关系如图7所示。650) this.width=650;" src="/KB/recipes/lib-conhash/map.JPG" alt="map" width="529" height="232" style="border:0" />图7 查询对象所在cache“虚拟节点”的hash计算可以采用对应节点的IP地址加数字后缀的方式。例如假设cache A的IP地址为202.168.14.241。引入“虚拟节点”前,计算cache A的hash值:Hash(“202.168.14.241”);引入“虚拟节点”后,计算“虚拟节”点cache A1和cache A2的hash值:Hash(“202.168.14.241#1”); &// cache A1Hash(“202.168.14.241#2”); &// cache A2参考文献:文章第五部分来自:本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)哈希算法,打造安全的密码体制 - 推酷
哈希算法,打造安全的密码体制
本文主要讨论了哈希算法的应用,而没有涉及非对称加密,对称加密等密码学的算法,但是还是先解释下密码学中的一些基础概念:
密钥:分为加密密钥和解密密钥。
明文:没有进行加密,能够直接代表原文含义的信息。
密文:经过加密处理处理之后,隐藏原文含义的信息。
加密:将明文转换成密文的实施过程。
解密:将密文转换成明文的实施过程。
密码算法:密码系统采用的加密方法和解密方法,随着基于数学密码技术的发展,加密方法一般称为加密算法,解密方法一般称为解密算法。
公开密钥加密(public-key cryptography,又译为公开密钥加密),也称为非对称加密(asymmetric cryptography),一种密码学算法类型,在这种密码学方法中,需要一对密钥,一个是私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。称公开的密钥为公钥;不公开的密钥为私钥。RSA 是常见的公钥加密算法。
对称密钥加密(Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥加密的主要缺点之一。常见的对称加密算法有 DES、3DES、AES 等
Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。
即小写字母 a-z、大写字母 A-Z、数字 0-9、符号 “+”、”/“(再加上作为垫字的 “=”,实际上是65个字符)作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。
具体来说,转换方式可以分为四步。
将每三个字节作为一组,一共是24个二进制位。
将这24个二进制位分为四组,每个组有6个二进制位。
在每组前面加两个00,扩展成32个二进制位,即四个字节。
根据 Base64 索引表,得到扩展后的每个字节的对应符号,这就是 Base64 的编码值。
第一步,”M”、”a”、”n”的 ASCII 值分别是77、97、110,对应的二进制值是101110,将它们连成一个24位的二进制字符串。
第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:、101110。
第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:101110。它们的十进制值分别是19、22、5、46。
第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。
var encodedData = window.btoa(&Hello, world&); // 编码
var decodedData = window.atob(encodedData); // 解码
注意:Base64 只是一种编码方式,并不是一种加密算法,不要使用 Base64 来加密数据。
哈希算法并不是一个特定的算法而是一类算法的统称。哈希算法也叫散列算法,一般来说满足这样的关系:f(data)=key,输入任意长度的 data 数据,经过哈希算法处理后输出一个定长的数据 key。同时这个过程是 不可逆 的,无法由 key 逆推出 data。
如果是一个 data 数据集,经过哈希算法处理后得到key的数据集,然后将 keys 与原始数据进行一一映射就得到了一个哈希表。一般来说哈希表 M 符合 M[key]=data 这种形式。
哈希表的好处是当原始数据较大时,我们可以用哈希算法处理得到定长的哈希值 key,那么这个 key 相对原始数据要小得多。我们就可以用这个较小的数据集来做索引,达到快速查找的目的。
稍微想一下就可以发现,既然输入数据不定长,而输出的哈希值却是固定长度的,这意味着哈希值是一个有限集合,而输入数据则可以是无穷多个。那么建立一对一关系明显是不现实的。 所以”碰撞”(不同的输入数据对应了相同的哈希值)是必然会发生的 ,所以一个成熟的哈希算法会有较好的抗冲突性。同时在实现哈希表的结构时也要考虑到哈希冲突的问题。
密码上常用的 MD5,SHA 都是哈希算法,因为 key 的长度(相对大家的密码来说)较大所以碰撞空间较大,有比较好的抗碰撞性,所以常常用作密码校验。
抗碰撞性使哈希算法对原始输入的任意一点更改,都会导致产生不同的哈希值,因此哈希算法可以用来检验数据的完整性。我们经常见到在一些网站下载某个文件时,网站还提供了此文件的哈希值,以供我们下载文件后检验文件是否被篡改。
不可逆的特性使哈希算法成为一种单向密码体制,只能加密不能解密,可以用来加密用户的登录密码等凭证。
消息摘要算法
哈希函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。而哈希算法的单向性使得要找到哈希值相同的两个不同的输入消息,在计算上是不可能的。所以数据的哈希值,即消息摘要,可以检验数据的完整性。
消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。
现在,消息摘要算法主要应用在“数字签名”领域,作为对明文的摘要算法。著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体。
MD5消息摘要算法
MD5消息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
SHA安全散列算法
安全散列算法(Secure Hash Algorithm)是一个密码散列函数家族,是FIPS所认证的五种安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。
String string=&SHA加密&;
System.out.println(&加密前的数据:& + string);
byte[] inputData = string.getBytes();
MessageDigest messageDigest = MessageDigest.getInstance(&SHA-256&);
messageDigest.update(inputData);
sha = new BigInteger(messageDigest.digest());
System.out.println(&SHA加密后的数据:& + sha.toString(32));
} catch (Exception e) {
e.printStackTrace();
打造安全的密码体制
哈希:不可逆加密
密码加密不同于普通的加密,一是内容重要,二是密码的验证根本不需要原文,要检查一个密码是否正确,只需要看它加密的结果与正确的密码加密的结果是否一致即可。确定了这两点,对于加密的方法,就只要求同一个字符串加密后会得到同样的密文。哈希完全满足了这一要求。
在哈希算法中,首选是 SHA2 系列,虽然安全性由于 SHA1 的原因而被质疑,但至少目前还没有证明有什么纰漏。MD5 由于用得太多,而且
实在过于泛滥,并不推荐使用。
另外一个问题,哈希一遍是不是就够了呢?当然不,不仅要多次哈希,而且还要与用户名一类的数据混加,比如,可以使用下面的方式来在客户端加密原始密码:
sha265(sha265(password)) + sha265(username)
这样,不仅可以增加密文反推原文的难度,还加入用户名,使得就算密码相同,不同用户的密文也完全不一样。
在客户端的加密,基本上也就只能到这一步了,因为一个最主要的问题是,客户端的加密算法是公开的。客户端加密的目的,在于保护用户的原始密码,不是为了防止被窃。
盐:混入随机数据
虽然在客户端对密码进行了加密,但无论是算法,还是混入的用户名,都是公开了的。剩下的加密,就需要留给后端了。
由于对同一字符串进行哈希的结果是恒定的,所以知道了算法和密文,理论上是可以反推出密码的,反推的难度取决于用户原始密码的复杂度。那如何才能够让反推的难度指数级增大呢?答案是在原始密码密文的基础之上,再加入一个随机字符串,从而达到让用户的密码更复杂的效果。这个随机字符串,便是盐。
后端获取到客户端传来的密码之后,再通过加盐哈希进行再加密。比如像下面这样:
sha256(username + sha256(password + salt)) + salt + sha256(username + salt)
注意,盐的保存非常关键,务必将它与用户信息分开存放。
在 HTTP 协议下,数据是明文传输,传输过程中网络嗅探可直接获取其中的数据。 如用户的密码和信用卡相关的资料,一旦被中间人获取,会给用户带来极大的安全隐患。
另一方面,在非加密的传输过程中,攻击者可更改数据或插入恶意的代码等。HTTPS 的诞生就是为了解决中间人攻击的问题,但如今 HTTPS 的使用情况在国内并不乐观,基本是因为成本或者性能的考量。
参考资料:
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 vivo手机x20 的文章

 

随机推荐