常见的加密算法

常用的加密算法有哪些

背景

为了防止自己的信息完全裸露在别人面前,就需要对信息进行加密。加密就是把明文以某种方式变换成一堆看起来乱七八糟的数据--密文,再把密文发给对方,对方收到之后,用对应的方法再用相应的方法再数据还原成明文(解密)。对信息进行加密的步骤就是加密算法。

有些算法本身,除了要输入明文之外,还需要输入另一个专门的数据(密钥)才能输出密文。现代的加密系统,一般都由加密算法和密钥组成。没有密钥的加密系统也是有的,但保密性和实用性相对来说比较差。比如一旦组织中有人离开,那么所有人都要更换加密算法,否则安全性就无法保证了。而带密钥的加密系统解决了这个问题。因为即使算法公开,没有密钥也无法解密密文信息,而密钥的更换比算法的更换要容易得多。

使用密码学可以达到以下目的:
保密性:防止用户的标识或数据被读取。
数据完整性:防止数据被更改。
身份验证:确保数据发自特定的一方。


 

常见的加密算法分类:

分类方法一:按照加密算法密钥是否对称,分成三类:对称加密算法非对称加密算法Hash算法

分类方法二:按照加密后的信息是否可以被还原,常用的加密算法分为两大类:可逆加密算法不可逆加密算法。
可逆加密算法:可逆加密算法又分为两大类:“对称式”和“非对称式”。
可逆加密算法

对称式加密 加密和解密使用同一个密钥,通常称之为“Session Key ”。这种加密技术目前被广泛采用,如美国政府所采用的DES加密标准就是一种典型的“对称式”加密法,它的Session Key长度为56Bits。

非对称式加密 加密和解密所使用的不是同一个密钥,而是两个密钥:一个称为“公钥”,另一个称为“私钥”;它们两个必须配对使用,否则不能打开加密文件。这里的“公钥”是指可以对外公布的,“私钥”则只能由持有人本人知道。它的优越性就在这里,因为如果是在网络上传输加密文件,对称式的加密方法就很难把密钥告诉对方,不管用什么方法都有可能被别人窃听到。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,不怕别人知道,收件人解密时只要用自己的私钥即可以,这样就很好地避免了密钥的传输安全性问题。

最典型的可逆加密算法是异或运算。大家都知道,对一个值连续异或两次,其结果还是原值;于是,第一次异或被看成是加密,第二次异或被看成是解密。

对EXE进行加密必须使用一些可逆的加密算法,即不仅能加密数据,还要能还原数据。下面我们就自行开发一种简单的可逆加密算法。

 
 
不可逆加密算法:其实就是Hash算法,或者叫单向散列算法
不可逆加密算法

不可逆加密算法的特征是,加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文。这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。

为了避免有人通过可逆算法得到加密前的信息,在用户权限认证的系统中,通常会使用一张不可逆加密的表,表中存放着经过加密以后的用户密码。这个密码是任何人也破解不了的,除非被他有幸猜中,虽然不能还原最初的密码,但可以通过对用户密码的再一次加密实现用户密码的验证。

举个最简单的例子:假设用户最初输入的密码是“123456”,使用的不可逆加密算法是将每一位当成一个数字,然后与3相除,取余数作为每一位加密后的结果,最终用户密码被加密成“120120”。很显然,你无法正确地还原回去,因为许多原始密码经过这种加密算法得到的值都是“120120”,如原始密码为“789123”、“456123”等。但是,这种加密算法却可以用在对用户的验证上,即用户只要输入“123456”,其加密以后的值一定是表中存储的值。

很明显,在这类加密过程中,加密是自己,解密还得是自己;而所谓解密,实际上就是重新加一次密,所应用的“密码”也就是输入的明文。

不可逆加密算法不存在密钥保管和分发问题,非常适合在分布式网络系统上使用,但因加密计算复杂,工作量相当繁重,通常只在数据量有限的情形下使用,例如,广泛应用在计算机系统中的口令加密,利用的就是不可逆加密算法。

近年来,随着计算机系统性能的不断提高,不可逆加密的应用领域正在逐渐增大。在计算机网络中应用较多不可逆加密算法的有许多,例如RSA公司发明的MD5算法,以及由美国国家标准局建议的不可逆加密标准SHS(Secure Hash Standard,安全散列信息标准)等。

 

什么是非对称加密算法?为什么需要非对称加密算法?

带密钥的加密算法一般分为两类:对称加密算法和非对称加密算法。

对称加密算法是指加密和解密使用相同,或是关连性很强的密钥。对称加密算法速度比较快,比较适合在大量数据加密的情况下使用。但对称加密要求通信双方能共享同一密钥,并对密钥进行严格地保护,否则密钥泄漏了,信息就被破解了。但在互联网的环境下,要达到这个要求是很难的。因为通信的对象多种多样,几乎不可能做到方便地共享同一密钥而不为人知。因为毕竟通信的双方很可能之前完全没有见接触过,是第一次通信,而他们的通信信息又希望被加密,比如我第一次登录亚马逊的网站买东西,那么如何与亚马逊共享同一密钥来保证我的帐户和密码的安全呢?对密钥本身已经无法加密了(对方根本无法解密)。把密钥发给对方,那就相当于也把密钥告诉了窃听者。所以共享密钥,同时对密钥严格保护,在现实中是非常困难的。

为了解决对称加密算法的问题,牛X的人发明了非对称加密算法。在非对称加密算法中,存在两个密钥。一个是加密密钥(e),一个解密密钥(d)。通过 e 对明文加密得到的密文,只有用 d 来解密出来还原成明文。而且算法本身可以保证,就算你知道 e ,想要得到 d 也是非常非常困难的。既然有这种特性,那么我们就可以这样做:我把加密密钥公布出去(发给通信的对方 A)。A 收到密钥 e 以后,用 e 对他要发送的信息(M)进行加密得到密文 C 发送给我,我再使用解密密钥 d 把密文解密,还原成 M。在这个过程中,我并不担心第三方的窃听者窃听我们的通信过程,因为就算他有了 e,也无法使用 e 来解密 C。除了解密密钥 d 的拥有者(我)之外,谁都无法解密。这样,我只要保证 d 的只有我知道(这个相对容易做到),就可以保证通信的安全。

不过,这世上没有彻头彻尾的绝望,也没有十全十美的事情。非对称加密算法一般都比较慢,需要耗费比较多的计算时间,并不适合用在大量的数据加密上。为了保证安全性,同时又降低计算上的需求,一般的通信应用都会结合使用对称加密算法和非对称加密算法。即,在通信的开始,先用非对称加密算法交换对称加密算法的密钥,之后再用对称加密算法进行通信。

image

 


对称加密
指加密和解密使用相同密钥的加密算法
对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要2个密钥并交换使用,如果企业内用户有n个,则整个企业共需要n×(n-1) 个密钥,密钥的生成和分发将成为企业信息部门的恶梦。对称加密算法的安全性取决于加密密钥的保存情况,但要求企业中每一个持有密钥的人都保守秘密是不可能的,他们通常会有意无意的把密钥泄漏出去——如果一个用户使用的密钥被入侵者所获得,入侵者便可以读取该用户密钥加密的所有文档,如果整个企业共用一个加密密钥,那整个企业文档的保密性便无从谈起。
常见的对称加密算法有DESAES3DESIDEARC4、RC5、RC6、Blowfish

非对称加密(公钥加密,私钥解密)
指加密和解密使用不同密钥的加密算法,也称为公私钥加密。
假设两个用户要加密交换数据,双方交换公钥,使用时一方用对方的公钥加密,另一方即可用自己的私钥解密。如果企业中有n个用户,企业需要生成n对密钥,并分发n个公钥。由于公钥是可以公开的,用户只要保管好自己的私钥即可,因此加密密钥的分发将变得十分简单。同时,由于每个用户的私钥是唯一的,其他用户除了可以可以通过信息发送者的公钥来验证信息的来源是否真实,还可以确保发送者无法否认曾发送过该信息。非对称加密的缺点是加解密速度要远远慢于对称加密,在某些极端情况下,甚至能比非对称加密慢上1000倍。
常见的非对称加密算法有:RSA、ECC(移动设备用)、DSA(数字签名用)、Diffie-Hellman、El Gamal

Hash算法(单向散列算法)
Hash算法特别的地方在于它是一种单向算法,散列是一种单向算法,一旦数据被转换,将无法再获得其原始值,;例如SHA1 和 MD5。用户可以通过Hash算法对目标信息生成一段特定长度的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。
常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1
加密算法的效能通常可以按照算法本身的复杂程度、密钥长度(密钥越长越安全)、加解密速度等来衡量。上述的算法中,除了DES密钥长度不够、MD2速度较慢已逐渐被淘汰外,其他算法仍在目前的加密系统产品中使用。
 
散列函数
又称Hash函数(也称杂凑函数或杂凑算法)就是把任意长的输入消息串变化成固定长的输出串的一种函数。这个输出串称为该消息的杂凑值。一般用于产生消息摘要,密钥加密等.
一个安全的杂凑函数应该至少满足以下几个条件:
①输入长度是任意的;
②输出长度是固定的,根据目前的计算技术应至少取128bits长,以便抵抗生日攻击;
③对每一个给定的输入,计算输出即杂凑值是很容易的
④给定杂凑函数的描述,找到两个不同的输入消息杂凑到同一个值是计算上不可行的,或给定杂凑函数的描述和一个随机选择的消息,找到另一个与该消息不同的消息使得它们杂凑到同一个值是计算上不可行的。
Hash函数主要用于完整性校验和提高数字签名的有效性,目前已有很多方案。这些算法都是伪随机函数,任何杂凑值都是等可能的。输出并不以可辨别的方式依赖于输入;在任何输入串中单个比特的变化,将会导致输出比特串中大约一半的比特发生变化。

常见散列函数(Hash函数)
①、MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值; 
②、SHA(Secure Hash Algorithm)这是一种较新的散列算法,可以对任意长度的数据运算生成一个160位的数值; 
③、MAC(Message Authentication Code):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息。HMAC(用于消息认证的密钥散列法)就是这种函数的一个例子。 
④、CRC(Cyclic Redundancy Check):循环冗余校验码CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。占用系统资源少,用软硬件均能实现,是进行数据传输差错检测地一种很好的手段(CRC 并不是严格意义上的散列算法,但它的作用与散列算法大致相同,所以归于此类)。
 

加密算法及分类

①、常见的对称加密算法:DES、AES、3DES、IDEA、DESX、RC4、RC5、RC6和Blowfish

       对称钥匙加密系统是加密和解密均采用同一把秘密钥匙,而且通信双方都必须获得这把钥匙,并保持钥匙的秘密。

②、常见的非对称加密算法:RSAECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

      非对称密钥加密系统采用的加密钥匙(公钥)和解密钥匙(私钥)是不同的。

③、常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1

 

 

注意:

Hash算法和MAC算法主要用来防篡改

数字签名算法主要用来进行身份认证和抗抵赖

 

算法推荐使用:

1.禁止使用业界已知不安全的加密算法,DES/3DES(除密钥K1,K2,K3三个密钥完全不同外的场景)/RC2/RSA(1024位及以下)/MD2/MD4。

2.禁止MD5算法应用参与生成“数字签名”,口令加密保存这两种场景;禁止SHA1应用参与生成“数字签名”的场景

3.推荐使用如下算法:

对称加密算法建议使用:AES(128位及以上);

非对称加密算法推荐使用:RSA(2048位及以上);

哈希算法推荐使用:SHA2(256位及以上);

HAMC(基于哈希的消息验证码)算法建议使用:HAMC_SHA2

缺省选择安全的加密算法。

 

非对称加密算法介绍:

RSA    RSA是Rivest、Shamir和Adleman提出来的基于数论非对称性(公开钥)加密算法。大整数的素因子难分解是RSA算法的基础。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。  RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA已经开始用于计算机网络加密,用来完成密钥分配、数字签名等功能。

DSA   DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准),严格来说不算加密算法;Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST(美国国家标准局)作为数字签名标准(DigitalSignature Standard)。同样属于公匙密码体系,并使用Secure Hash Algorithm(SHA/SHA-1)作为中间单向计算算法。

DH     Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。

ECDSA  椭圆曲线数字签名算法(ECDSA)设计的数学原理是基于椭圆曲线离散对数问题的难解性。EC点上离散对数的研究现状表明:所使用的ECDSA密钥至少需要192比特,才能保证有足够的中长期安全。RC2是由著名密码学家Ron Rivest设计的一种传统对称分组加密算法,它可作为DES算法的建议替代算法。它的输入和输出都是64比特。密钥的长度是从8字节到128字节可变,但目前的实现是8字节(1998年)。


RC4  RC4加密算法是大名鼎鼎的RSA三人组中的头号人物Ron Rivest在1987年设计的密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。该算法的速度可以达到DES加密的10倍左右 ,且具有很高级别的非线性。RC4起初是用于保护商业机密的。但是在1994年9月,它的算法被发布在互联网上,也就不再有什么商业机密了。RC4也被叫做ARC4(Alleged RC4——所谓的RC4),因为RSA从来就没有正式发布过这个算法。     

RC5  RC5密码是1994由麻萨诸塞技术研究所的RonaldL.Rivest教授发明的。它是一种非常快速且简单的算法由块尺寸,轮数,和密钥长度参数化。这些参数能被调整以满足不同的安全目的,性能和出口能力。 合并的RSA数据安全已经归档了RC5密码的专利的申请和RC5,RC5-CBC,RC5-CBC-Pad,RC5-CTS并分类了各种变更

DES   DES(Data Encryption Standard)对称算法,数据加密标准,速度较快,适用于加密大量数据的场合;数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的密钥系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的。通常,自动取款机(Automated Teller Machine,ATM)都使用DEA。它出自IBM的研究工作,IBM也曾对它拥有几年的专利权,但是在1983年已到期后,处于公有范围中,允许在特定条件下可以免除专利使用费而使用。1977年被美国政府正式采纳。还有DES2和DES3等算法。         

3DES 3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条64位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。是基于DES的对称算法,对一块数据用三个不同的密钥进行三次加密,强度更高;

       
IDEA IDEA(International Data Encryption Algorithm)国际数据加密算法,使用 128 位密钥提供非常强的安全性。   IDEA(International Data Encryption Algorithm)是瑞士的James Massey,Xuejia  Lai等人提出的加密算法,在密码学中属于数据块加密算法(Block Cipher)类。 IDEA使用长度为128bit的密钥,数据块大小为64bit。从理论上讲,IDEA属于“强”加密算法,至今还没有出现对该算法的有效攻击算法

SKIPJACK  Skipjack分组加密算法是由美国国家安全局(NSA)从1985年开始设计,1990年完成评估,于1993年由美国政府正式对外宣布的,是"Capstone"(美国政府根据1987年国会通过的计算机安全法案所订立的长远计划)中的一个项目(另外三 个项目分别是数字签名标准(DSA)、安全散列函数(SHA)及密钥交换方法)。Skipjack算法曾经被列为“机密”等级。


AES   AES(Advanced Encryption Standard):高级加密标准对称算法,是下一代的加密算法标准,速度快,安全级别高,在21世纪AES 标准的一个实现是 Rijndael 算法;随着对称密码的发展,DES数据加密标准算法由于密钥长度较小(56位),已经不适应当今分布式开放网络对数据加密安全性的要求,因此1997年NIST公开征集新的数据加密标准,即AES[1]。经过三轮的筛选,比利时Joan Daeman和Vincent Rijmen提交的Rijndael算法被提议为AES的最终算法。此算法将成为美国新的数据加密标准而被广泛应用在各个领域中。尽管人们对AES还有不同的看法,但总体来说,AES作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和 256 位密钥,并且用 128 位(16字节)分组加密和解密数据


TWOFISH       在1972到1974年中,National Bureau of Standards (现在更名为National Institute of Standards and Tecnology,缩写为NIST)首次公开征求一种标准的数据加密算法,结果产生了 DES ( Data Encryption Standard) 加密算法。

SHA  SHA(即Secure Hash Algorlthm,安全散列算法)是一种常用的数据加密算法.它由美国国家标准与技术局(Natlonal Instituteof Standards and Technology)于1993年作为联邦信息处理标准公布(即第一代SHA算法——SHA-0) 。在1995年和2002年.其改进版本SHA-1、SHA-2也分别正式公布(SHA-1和SHA-2具有比SHA-0更高的安全性)。SHA算法与MD5算法的设计原理类似.同样也按2blt数据块为单位来处理输入

SHA-1  SHA-1杂凑算法起初是针对DSA算法而设计的,其设计原理与Ron Rivest提出的MD2,MD4,尤其是MD5杂凑函数的设计原理类似。

ECC  2000年10月,国际密码学界在德国ESSEN召开了学术大会(ECC2000),在这次会议上,来自世界各国的密码学家、数学家证明了对ECC算法的最快破解效率是高于亚指数级的,而RSA算法的最快破解效率是亚指数级的。ECC2000的召开 进一步从学术上奠定了ECC算法的安全性,极大的推动了它在世界各国的应用。

MD2  Rivest在1989年开发出MD2算法。在这个算法中,首先对信息进行数据补位,使信息的字节长度是16的倍数。然后,以一个16位的检验和追加到信息末尾。并且根据这个新产生的信息计算出散列值。后来,Rogier和Chauvaud发现如果 忽略了检验将和MD2产生冲突。MD2算法加密后结果是唯一的-----即没有重复。

MD4  MD4是麻省理工学院教授Ronald Rivest于1990年设计的一种信息摘要算法。它是一种用来测试信息完整性的密码散列函数的实行。其摘要长度为128位。这个算法影响了后来的算法如MD5、SHA 家族和RIPEMD等。

MD5  MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。

HAMC  HAMC是密钥相关的哈希运算消息认证码(keyed-Hash Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。    HMAC引擎提供HMAC运算功能,发挥两方面的作用:   (1)验证TPM接受的授权数据和认证数据;      (2)确认TPM接受到的命令请求是已授权的请求,并且,命令在传送的过程中没有被改动过。

HMAC_SHA1  HMAC_SHA1(Hashed Message Authentication Code, Secure Hash Algorithm)是一种安全的基于加密hash函数和共享密钥的消息认证协议。它可以有效地防止数据在传输过程中被截获和篡改,维护了数据的完整性、可靠性和安全性。

HMAC_SHA1消息认证机制的成功在于一个加密的hash函数、一个加密的随机密钥和一个安全的密钥交换机制。

HMAC_SHA1 其实还是一种散列算法,只不过是用密钥来求取摘要值的散列算法。

HMAC_SHA1算法在身份验证和数据完整性方面可以得到很好的应用,在目前网络安全也得到较好的实现

SCB2  SCB2 算法是国家密码管理局推出的一款对称分组密码算法,与以往的对称分组密码算法相比具有安全性高,加解密性能快等特点,因此目前 SCB2 算法成为国家主管部门在商用密码领域主力推广使用的对称分组密码算法。 SCB2 算法可以用于各种文件传输过程中进行加解密的安全文件传输系统。目前,该领域主要有使用县乡专用SCB2 算法的安全文件传输系统如: SJY117 和使用通用 SCB2 算法的安全文件传输系统

SSF33  国内的一些行业应用智能卡规范中,凡是涉及到CPU卡的大多会提到采用SSF33算法。但是目前在任何公开的资料中始终不能找到SSF33算法的详细内容,开始的时候大家都疑窦丛生,后来也就习以为常见怪不怪了。因为虽然规范中定义了SSF33算法,但是在实际应用中几乎都不使用这套算法。尤其是针对那些需要在国际间实现互联互通的领域,比如银行卡方面,从来就没用过SSF33算法。

 

小知识之HMAC:

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC加密算法引入了密钥,其安全性已经不完全依赖于所使用的HASH算法。HMAC即带密钥的HASH函数,用它产生的报文鉴别码(MAC)可以实现报文鉴别

HMACSHA1 是从 SHA1 哈希函数构造的一种键控哈希算法,被用作 HMAC(基于哈希的消息验证代码)。 此 HMAC 进程将密钥与消息数据混合,使用哈希函数对混合结果进行哈希计算,将所得哈希值与该密钥混合,然后再次应用哈希函数。 输出的哈希值长度为 160 位。

在发送方和接收方共享机密密钥的前提下,HMAC 可用于确定通过不安全信道发送的消息是否已被篡改。 发送方计算原始数据的哈希值,并将原始数据和哈希值放在一个消息中同时传送。 接收方重新计算所接收消息的哈希值,并检查计算所得的 HMAC 是否与传送的 HMAC 匹配。

因为更改消息和重新生成正确的哈希值需要密钥,所以对数据或哈希值的任何更改都会导致不匹配。 因此,如果原始的哈希值与计算得出的哈希值相匹配,则消息通过身份验证。

SHA-1(安全哈希算法,也称为 SHS、安全哈希标准)是由美国政府发布的一种加密哈希算法。 它将从任意长度的字符串生成 160 位的哈希值。

HMACSHA1 接受任何大小的密钥,并产生长度为 160 位的哈希序列。

 

简要介绍DES、RSA MD5 SHA1 四种加密算法的优缺点,以及使用场合

美国数据加密标准(DES)是对称密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。密钥较短,加密处理简单,加解密速度快,适用于加密大量数据的场合。
RSA是非对称算法,加密密钥和解密密钥是不一样的,或者说不能由其中一个密钥推导出另一个密钥。密钥尺寸大,加解密速度慢,一般用来加密少量数据,比如DES的密钥。
SHA1 和 MD5 是散列算法,将任意大小的数据映射到一个较小的、固定长度的唯一值。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。MD5 比 SHA1 大约快 33%。

加密算法的选择

我们应该根据自己的使用特点来确定,由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。

对称加密算法不能实现签名,因此签名只能非对称算法

由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。

    在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

    如果在选定了加密算法后,那采用多少位的密钥呢?一般来说,密钥越长,运行的速度就越慢,应该根据的我们实际需要的安全级别来选择,一般来说,RSA建议采用1024位的数字,ECC建议采用160位,AES采用128为即可。

 

.          加密算法介绍

对称加密算法

对称加密算法用来对敏感数据等信息进行加密,常用的算法包括:

DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。

3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。

AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;

AES与3DES的比较

算法名称

算法类型

密钥长度

速度

解密时间(建设机器每秒尝试255个密钥)

资源消耗

AES

对称block密码

128、192、256位

1490000亿年

3DES

对称feistel密码

112位或168位

46亿年

非对称算法

RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;

DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);

ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

ECC和RSA相比,在许多方面都有对绝对的优势,主要体现在以下方面:

抗攻击性强。相同的密钥长度,其抗攻击性要强很多倍。

计算量小,处理速度快。ECC总的速度比RSA、DSA要快得多。

存储空间占用小。ECC的密钥尺寸和系统参数与RSA、DSA相比要小得多,意味着它所占的存贮空间要小得多。这对于加密算法在IC卡上的应用具有特别重要的意义。

带宽要求低。当对长消息进行加解密时,三类密码系统有相同的带宽要求,但应用于短消息时ECC带宽要求却低得多。带宽要求低使ECC在无线网络领域具有广泛的应用前景。

下面两张表示是RSA和ECC的安全性和速度的比较。

攻破时间(MIPS年)

RSA/DSA(密钥长度)

ECC密钥长度

RSA/ECC密钥长度比

104

512

106

5:1

108

768

132

6:1

1011

1024

160

7:1

1020

2048

210

10:1

1078

21000

600

35:1

 

攻破时间(MIPS年)

RSA/DSA(密钥长度)

ECC密钥长度

RSA/ECC密钥长度比

104

512

106

5:1

108

768

132

6:1

1011

1024

160

7:1

1020

2048

210

10:1

1078

21000

600

35:1

RSA和ECC安全模长得比较

功能

Security Builder 1.2

BSAFE 3.0

163位ECC(ms)

1,023位RSA(ms)

密钥对生成

3.8

4,708.3

签名

2.1(ECNRA)

228.4

3.0(ECDSA)

认证

9.9(ECNRA)

12.7

10.7(ECDSA)

Diffie—Hellman密钥交换

7.3

1,654.0

RSA和ECC速度比较

散列算法

散列是信息的提炼,通常其长度要比信息小得多,且为一个固定长度。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同散列结果的两条信息。具有这些特性的散列结果就可以用于验证信息是否被修改。

单向散列函数一般用于产生消息摘要,密钥加密等,常见的有:

l         MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,非可逆,相同的明文产生相同的密文。

l         SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

SHA-1MD5的比较

因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

l         对强行供给的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2128数量级的操作,而对SHA-1则是2160数量级的操作。这样,SHA-1对强行攻击有更大的强度。

l         对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。

l         速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

对称与非对称算法比较

    以上综述了两种加密方法的原理,总体来说主要有下面几个方面的不同:

l         在管理方面:公钥密码算法只需要较少的资源就可以实现目的,在密钥的分配上,两者之间相差一个指数级别(一个是n一个是n2)。所以私钥密码算法不适应广域网的使用,而且更重要的一点是它不支持数字签名。

l         在安全方面:由于公钥密码算法基于未解决的数学难题,在破解上几乎不可能。对于私钥密码算法,到了AES虽说从理论来说是不可能破解的,但从计算机的发展角度来看。公钥更具有优越性。

l         从速度上来看:AES的软件实现速度已经达到了每秒数兆或数十兆比特。是公钥的100倍,如果用硬件来实现的话这个比值将扩大到1000倍。

三.            加密算法的选择

由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。

对称加密算法不能实现签名,因此签名只能非对称算法。

由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。

在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

那采用多少位的密钥呢? RSA建议采用1024位的数字,ECC建议采用160位,AES采用128为即可。

四.            密码学在现代的应用

保密通信:保密通信是密码学产生的动因。使用公私钥密码体制进行保密通信时,信息接收者只有知道对应的密钥才可以解密该信息。

数字签名:数字签名技术可以代替传统的手写签名,而且从安全的角度考虑,数字签名具有很好的防伪造功能。在政府机关、军事领域、商业领域有广泛的应用环境。

秘密共享:秘密共享技术是指将一个秘密信息利用密码技术分拆成n个称为共享因子的信息,分发给n个成员,只有k(k≤n)个合法成员的共享因子才可以恢复该秘密信息,其中任何一个或m(m≤k)个成员合作都不知道该秘密信息。利用秘密共享技术可以控制任何需要多个人共同控制的秘密信息、命令等。

认证功能:在公开的信道上进行敏感信息的传输,采用签名技术实现对消息的真实性、完整性进行验证,通过验证公钥证书实现对通信主体的身份验证。

密钥管理:密钥是保密系统中更为脆弱而重要的环节,公钥密码体制是解决密钥管理工作的有力工具;利用公钥密码体制进行密钥协商和产生,保密通信双方不需要事先共享秘密信息;利用公钥密码体制进行密钥分发、保护、密钥托管、密钥恢复等。

基于公钥密码体制可以实现以上通用功能以外,还可以设计实现以下的系统:安全电子商务系统、电子现金系统、电子选举系统、电子招投标系统、电子彩票系统等。

 

对称加密 非对称加密 不可逆加密算法

 

根据密钥类型不同可以将现代密码技术分为两类:对称加密算法(私钥密码体系)和非对称加密算法(公钥密码体系)。

1 对称加密算法中,数据加密和解密采用的都是同一个密钥,因而其安全性依赖于所持有密钥的安全性。 对称加密算法的主要优点是加密和解密速度快,加密强度高,且算法公开. 缺点是实现密钥的秘密分发困难,在大量用户的情况下密钥管理复杂,而且无法完成身份认证等功能,不便于应用在网络开放的环境中。 对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。 目前最著名的对称加密算法有数据加密标准DES,但传统的DES由于只有56位的密钥,因此已经不适应当今分布式开放网络对数据加密安全性的要求。欧洲数据加密标准IDEA等,目前加密强度最高的对称加密算法是高级加密标准AES,AES提供128位密钥,128位AES的加密强度是56位DES加密强度的1021倍还多。。

对称加密算法过程是将数据发信方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。 不足之处是,交易双方都使用同样钥匙,安全性得不到保证。假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要2个密钥并交换使用,如果企业内用户有n个,则整个企业共需要n×(n-1) 个密钥。

2 非对称加密算法   非对称加密算法使用两把完全不同但又是完全匹配的一对钥匙(即一把公开密钥或加密密钥和专用密钥或解密密钥)—公钥和私钥。在使用不对称加密算法加密文件时,只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。加密明文时采用公钥加密,解密密文时使用私钥才能完成,而且发信方(加密者)知道收信方的公钥,只有收信方(解密者)才是唯一知道自己私钥的人。非对称加密算法的基本原理是,如果发信方想发送只有收信方才能解读的加密信息,发信方必须首先知道收信方的公钥,然后利用收信方的公钥来加密原文;收信方收到加密密文后,使用自己的私钥才能解密密文。 广泛应用的非对称加密算法有RSA算法和美国国家标准局提出的DSA。 非对称加密算法的保密性比较好,它消除了最终用户交换密钥的需要,但加密和解密花费时间长、速度慢,它不适合于对文件加密而只适用于对少量数据进行加密。

对称加密算法、非对称加密算法和不可逆加密算法可以分别应用于数据加密、身份认证和数据安全传输。

3 不可逆加密算法

 不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。显然,在这类加密过程中,加密是自己,解密还得是自己,而所谓解密,实际上就是重新加一次密,所应用的“密码”也就是输入的明文。不可逆加密算法不存在密钥保管和分发问题,非常适合在分布式网络系统上使用,但因加密计算复杂,工作量相当繁重,通常只在数据量有限的情形下使用,如广泛应用在计算机系统中的口令加密,利用的就是不可逆加密算法。近年来,随着计算机系统性能的不断提高,不可逆加密的应用领域正在逐渐增大。在计算机网络中应用较多不可逆加密算法的有RSA公司发明的MD5算法和由美国国家标准局建议的不可逆加密标准SHS(Secure Hash Standard:安全杂乱信息标准)等。

 

比较著名的

1 对称     DES

2 不对称  RSA

3 不可逆  MD5

 

21.2 加密算法

加密算法是EXE加密的核心。本节首先介绍了常用的两类加密算法,然后介绍了自行设计的可逆加密算法,并给出了加密代码。

21.2.1 

 

2 各类算法的优缺点

对称加密:加解密速度快 密钥管理困难 主要用于大数据量的加密

非对称加密:密钥管理方便 加解密速度慢 主要用于密钥交互密钥的管理

通常是对称加密、非对称加密、Hash算法解密相结合:

例如 某流行IM软件的全流程加密过程:

登录过程:客户端到服务器交互用户的信息:(设备型号,密码MD5值,版本信息等)用的RSA 1024位加密)用于用户信息的验证

                  服务器到客户端的回应信息:(后续数据交互过程加解密的KEY) 采用的是AES 128 位 KEY 是 密码MD5 后前16个字符

数据交互过程:采用的AES 128位加密 解密KEY: 登录过程中服务器到客户端回应信息中包含的KEY。

此全流程数据的加密是三类加密算法的完美结合,也是一种非常完美的IM类软件的加解密方案。可以做为其他IM类软件解密方案模板。

 

“盐”值

盐值也可以为您提供一层额外的安全保护。使用 .NET Framework 类 RNGCryptoServiceProvider 创建一个随机的数字字符串。RNG 表示随机数生成器。该类可以创建一个任意长度的随机字节数组,长度可以被指定。根据盐值&口令一道提交加密。

 

浅谈MD5加密算法中的加盐值(SALT)

您是否遇见过破解不了的MD5值?你是否遇见过‘奇形怪状’的hash?这些非常有可能就是带有salt(俗称加盐值),本文将为大家简单的介绍关于加盐值的一些信息。

0×01. 什么是加盐值? 为了加强MD5的安全性(本身是不可逆的),从而加入了新的算法部分即加盐值,加盐值是随机生成的一组字符串,可以包括随机的大小写字母、数字、字符,位数可以根据要求而不一样,使用不同的加盐值产生的最终密文是不一样的。

0×02. 代码中如何使用加盐值? 由于使用加盐值以后的密码相当的安全,即便是你获得了其中的salt和最终密文,破解也是一个耗费相当多时间的过程,可以说是破解单纯MD5的好几倍,那么使用加盐值以后的密文是如何产生的呢? 1).首先我们得到的是明文的hash值 2).进行计算获取MD5明文hash值 3).随机生成加盐值并插入 4).MD5插入加盐值得到的hash 5).得到最终的密文

0×03. 如何破解出带有加盐值的密文 因为像windows hash(未进行syskey加密)、非加盐值MD5等都可以通过大型的密码(如彩虹表)表进行对比解密,所以相对而言相当的轻松,而带有加盐值的密文就相对而言复杂的多,现在的MD5表大概是260+G,如何加盐值的可能性有10000个,那么密码表的应该是MD5 size*10000,就可以解密出原MD5表能够解密的密码了,一些网站也提供了对应的salt解密,但是测试以后效果并不是非常好,如常规的admin888也未解密出,实在是遗憾,毕竟MD5本是不可逆的,带入随机值解密出最终密码的可能性就更低了,至少是相对大多数人而言的。

0×04. 含加盐值MD5算法的应用 目前多家的网站程序公司都已经加入了该算法,如常见的VBB论坛、discuz论坛等都采用了,甚至著名的Linux开源操作系统早已经加入了这种加密模式。可得而知,这种算法势必会在未来应用于更多的范围。

*0×05. 如何渗透带有加盐值的站点(实际案例)? 这一段信息是来源于我近日实际渗透的片段,由于通过多种途径无法解密带有加盐值的密文,所以只能通过其他方式进行突破,本欲修改管理员密码来进行操作,但站点是通过多个网站对比密码的形式,如站A和站B,我如果修改站A的密码,一旦对比站A和站B,那么将会提示无法登陆,因为我只拥有一个站的管理权限,那么这样就非常的麻烦了,一是密文无法破解,而是修改密码无效。那么我们应该如何处理呢?这里简述下本人在这里应用的方法:

1).修改admin uid为没有启用的某值

2).将自己的注册用户修改为admin uid的值

重新登陆,并成功获取权限,因为在站A中式依据uid来分配权限的,也就是给某uid管理员权限,如何而言轻松获取到管理员权限。

 

什么叫盐值加密 Spring security怎样进行盐值加密 
以前的md5原理是 
密码密文=md5算法(密码明文); 
这样明文与密文其实还是一一对应的 
那么人家就可以用字典攻击(就是一个一个的试)来探测密码 
加盐(盐值加密)的算法很多 
Spring security用的是: 
密码密文=md5算法(密码明文{盐值}); 
这个盐值就可以自己随便设置了,弄一个静态字符串或者用用户的登录名 
举个例子: 
用户名:thr 
密码:fou 
用用户名作为盐值 
打开网页:http://www.md5.org.cn/md5/Encrypt.asp 
输入:thr{fou} 
得到密文:5dbae131e3eea6ce50068aab9292c8c3 
OK.应该明白了

 

先说一下 MD5吧!虽然md5算法是不可逆的,但是因为它对同一个字符
串计算的结果是唯一的,所以一些人可能会使用“字典攻击”的方式来攻破md5加密的系统[5]。这虽然属于暴力解密,却十分有效,因为大多数系统的用户密码都不回很长。
为了解决这个问题,我们可以使用盐值加密“salt-source”。

 

 

 

浅谈MD5加密算法中的加盐值(SALT)

分类: 学习笔记

本文来自 blade2001的专栏

 


 

我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。

  加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。

  这里的“佐料”被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过自己的密码和自己生成的散列值来找具有特定密码的用户,但这个几率太小了(密码和salt值都得和黑客使用的一样才行)。

下面以PHP示例,讲解md5($pass.$salt)加密函数。

<?php function hash($a) {     $salt=”Random_KUGBJVY”;  //定义一个salt值,程序员规定下来的随机字符串     $b=$a.$salt;  //把密码和salt连接     $b=md5($b);  //执行MD5散列     return $b;  //返回散列     } ?>

  调用方式:$new_password=hash($_POST[password]);   //这里接受表单提交值,并进行加密

  下面详细介绍一下加Salt散列的过程。介绍之前先强调一点,前面说过,验证密码时要使用和最初散列密码时使用“相同的”佐料。所以Salt值是要存放在数据库里的。

用户注册时,

  1. 用户输入【账号】和【密码】(以及其他用户信息);
  2. 系统为用户生成【Salt值】;
  3. 系统将【Salt值】和【用户密码】连接到一起;
  4. 对连接后的值进行散列,得到【Hash值】;
  5. 将【Hash值1】和【Salt值】分别放到数据库中。

用户登录时,

  1. 用户输入【账号】和【密码】;
  2. 系统通过用户名找到与之对应的【Hash值】和【Salt值】;
  3. 系统将【Salt值】和【用户输入的密码】连接到一起;
  4. 对连接后的值进行散列,得到【Hash值2】(注意是即时运算出来的值);
  5. 比较【Hash值1】和【Hash值2】是否相等,相等则表示密码正确,否则表示密码错误。

有时候,为了减轻开发压力,程序员会统一使用一个salt值(储存在某个地方),而不是每个用户都生成私有的salt值。

 

 

 

 

您是否遇见过破解不了的MD5值?你是否遇见过‘奇形怪状’的hash?这些非常有可能就是带有salt(俗称加盐值),本文将为大家简单的介绍关于加盐值的一些信息。

0×01. 什么是加盐值? 为了加强MD5的安全性(本身是不可逆的),从而加入了新的算法部分即加盐值,加盐值是随机生成的一组字符串,可以包括随机的大小写字母、数字、字符,位数可以根据要求而不一样,使用不同的加盐值产生的最终密文是不一样的。

 

0×02. 代码中如何使用加盐值? 由于使用加盐值以后的密码相当的安全,即便是你获得了其中的salt和最终密文,破解也是一个耗费相当多时间的过程,可以说是破解单纯MD5的好几倍,那么使用加盐值以后的密文是如何产生的呢? 1).首先我们得到的是明文的hash值 2).进行计算获取MD5明文hash值 3).随机生成加盐值并插入 4).MD5插入加盐值得到的hash 5).得到最终的密文

 

0×03. 如何破解出带有加盐值的密文 因为像windows hash(未进行syskey加密)、非加盐值MD5等都可以通过大型的密码(如彩虹表)表进行对比解密,所以相对而言相当的轻松,而带有加盐值的密文就相对而言复杂的多,现在的MD5表大概是260+G,如何加盐值的可能性有10000个,那么密码表的应该是MD5 size*10000,就可以解密出原MD5表能够解密的密码了,一些网站也提供了对应的salt解密,但是测试以后效果并不是非常好,如常规的admin888也未解密出,实在是遗憾,毕竟MD5本是不可逆的,带入随机值解密出最终密码的可能性就更低了,至少是相对大多数人而言的。

 

0×04. 含加盐值MD5算法的应用 目前多家的网站程序公司都已经加入了该算法,如常见的VBB论坛、discuz论坛等都采用了,甚至著名的Linux开源操作系统早已经加入了这种加密模式。可得而知,这种算法势必会在未来应用于更多的范围。

 

*0×05. 如何渗透带有加盐值的站点(实际案例)? 这一段信息是来源于我近日实际渗透的片段,由于通过多种途径无法解密带有加盐值的密文,所以只能通过其他方式进行突破,本欲修改管理员密码来进行操作,但站点是通过多个网站对比密码的形式,如站A和站B,我如果修改站A的密码,一旦对比站A和站B,那么将会提示无法登陆,因为我只拥有一个站的管理权限,那么这样就非常的麻烦了,一是密文无法破解,而是修改密码无效。那么我们应该如何处理呢?这里简述下本人在这里应用的方法: 1).修改admin uid为没有启用的某值 2).将自己的注册用户修改为admin uid的值 重新登陆,并成功获取权限,因为在站A中式依据uid来分配权限的,也就是给某uid管理员权限,如何而言轻松获取到管理员权限。

 

 

6.2. 盐值加密

实际上,上面的实例在现实使用中还存在着一个不小的问题。虽然md5算法是不可逆的,但是因为它对同一个字符串计算的结果是唯一的,所以一些人可能会使用“字典攻击”的方式来攻破md5加密的系统[5]。这虽然属于暴力解密,却十分有效,因为大多数系统的用户密码都不回很长。

实际上,大多数系统都是用admin作为默认的管理员登陆密码,所以,当我们在数据库中看到“21232f297a57a5a743894a0e4a801fc3”时,就可以意识到admin用户使用的密码了。因此,md5在处理这种常用字符串时,并不怎么奏效。

为了解决这个问题,我们可以使用盐值加密“salt-source”。

修改配置文件:

<authentication-provider> <password-encoder hash="md5"> <salt-source user-property="username"/></password-encoder> <jdbc-user-service data-source-ref="dataSource"/> </authentication-provider>

在password-encoder下添加了salt-source,并且指定使用username作为盐值。

盐值的原理非常简单,就是先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算,这样一来,就算密码是一个很常见的字符串,再加上用户名,最后算出来的md5值就没那么容易猜出来了。因为攻击者不知道盐值的值,也很难反算出密码原文。

我们这里将每个用户的username作为盐值,最后数据库中的密码部分就变成了这样:

INSERT INTO USERS VALUES('admin','ceb4f32325eda6142bd65215f4c0f371',TRUE) INSERT INTO USERS VALUES('user','47a733d60998c719cf3526ae7d106d13',TRUE)

 

   在 Spring Security 文档中有这么一句话: "盐值的原理非常简单,就是先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算,这样一来,就算密码是一个很常见的字符串,再加上用户名,最后算出来的md5值就没那么容易猜出来了。因为攻击者不知道盐值的值,也很难反算出密码原文。"

     呵呵, 问题如何理解这句话: "先把密码和盐值指定的内容合并在一起,再使用md5对合并后的内容进行演算".  例如, 在 applicationContext-security.xml 文件中的配置如下:

  

[xhtml] view plaincopy
  1. <authentication-provider user-service-ref="userDetailsService">     
  2.      <password-encoder hash="md5">  
  3.          <!-- 将每个用户的username作为盐值 -->  
  4.          <salt-source user-property="username"/>  
  5.      </password-encoder>  
  6. </authentication-provider>  

 

   假设用户名是 Tom, 密码为 123456, 那么在数据库中存放的值应该是什么?

   通过查看 Spring Security 的 org.springframework.security.providers.encoding.BasePasswordEncoder 类可知 Spring Security 通过如下方式来匹配在数据库中已经被盐值加密的密码:  

  1. protected String mergePasswordAndSalt(String password, Object salt, boolean strict) {  
  2.         if (password == null) {  
  3.             password = "";  
  4.         }  
  5.   
  6.         if (strict && (salt != null)) {  
  7.             if ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1)) {  
  8.                 throw new IllegalArgumentException("Cannot use { or } in salt.toString()");  
  9.             }  
  10.         }  
  11.   
  12.         if ((salt == null) || "".equals(salt)) {  
  13.             return password;  
  14.         } else {  
  15.             return password + "{" + salt.toString() + "}";  
  16.         }  
  17. }  

 

   即通过 password + "{" + salt.toString() + "}" 中方式把 "密码和盐值指定的内容合并在一起". 所以对于用户名是 Tom, 密码为 123456 的用户在数据库中存放的密码应该为对 "123456{Tom}" md5 验算后的值: 610c492873b994f96f93e342a56bcd68

给MD5加点“盐”
   
虽然MD5加密很厉害,将 信息泄露的概率降低到了非常小的程度,但我们这些做程序员的具有追求完美的天性,为了达到更高的安全级别,我们还需给MD5加点“盐”。所谓的加“盐”就 是当用户注册填写密码时,让系统产生一个随机值,将这个值与用户密码连接在一起再使用MD5算法进行处理,这样就在很大程度上避免了攻击者通过字符对比得 到特定密码的危险。

在CBC(不光是DES算法)模式下,iv通过随机数(或伪随机)机制产生是一种比较常见的方法。iv的作用主要是用于产生密文的第一个block,以使最终生成的密文产生差异(明文相同的情况下),使密码攻击变得更为困难,除此之外iv并无其它用途。因此iv通过随机方式产生是一种十分简便、有效的途径。此外,在IPsec中采用了DES-CBC作为缺省的加密方式,其使用的iv是通讯包的时间戳。从原理上来说,这与随机数机制并无二致。

看来,向量的作用其实就是salt

最大的好处是,可以令到即使相同的明文,相同的密钥,能产生不同的密文

例如,我们用DES方式在数据保存用户密码的时候,可以另外增加一列,把向量同时保存下来,并且每次用不同的向量。这样的好处是,即使两个用户的密码是一样的,数据库保存的密文,也会不一样,就能降低猜测的可能性。

如基本的单向加密算法: 

    • BASE64 严格地说,属于编码格式,而非加密算法
    • MD5(Message Digest algorithm 5,信息摘要算法)
    • SHA(Secure Hash Algorithm,安全散列算法)
    • HMAC(Hash Message Authentication Code,散列消息鉴别码)

IV:初始化向量

 
 
IV:初始化向量   
MSDN:基类库中提供的块密码类使用称作密码块链    (CBC)    的链模式,它使用一个密钥和一个初始化向量    (IV)    对数据执行加密转换。对于给定的私钥    k,一个未使用初始化向量的简单块密码将把相同的明文输入块加密为同样的密文输出块。如果在明文流内有重复的块,那么在密文流内也会有重复的块。如果未经授权的用户知道有关明文块的结构的所有信息,就可以使用该信息解密已知的密文块并有可能获得您的密钥。若要克服这个问题,可将上一个块中的信息混合到加密下一个块的过程中。这样,两个相同的明文块的输出就会不同。由于该技术使用上一个块加密下一个块,因此使用了一个    IV    来加密数据的第一个块。使用该系统,未经授权的用户有可能知道的公共消息标头将无法用于对密钥进行反向工程。
优点:1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的 标准。
缺点:1.不利于并行计算;2.误差传递;3.需要初始化向量IV
http://blog.csdn.net/aaaaatiger/archive/2008/06/08/2525561.aspx
 

分组对称加密模式:ECB/CBC/CFB/OFB

 

一般的加密通常都是块加密,如果要加密超过块大小的数据,就需要涉及填充和链加密模式,文中提到的ECB和CBC等就是指链加密模式。在C#组件中实现的很多算法和Java都不太兼容,至少我发现RSA和AES/ECB是如此。研究了AES/ECB时发现了这篇文档,图还画的不错,先记下。注意,还缺一种CTR的模式。

 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)

. AES对称加密:
                                                      AES加密
                         分组
 
 
. 分组密码的填充
                                                   分组密码的填充
 
e.g.:                                                          PKCS#5填充方式
 
 
 
. 流密码:

 
 
. 分组密码加密中的四种模式:
3.1 ECB模式
优点:
1.简单;
2.有利于并行计算;
3.误差不会被传送;
缺点:
1.不能隐藏明文的模式;
2.可能对明文进行主动攻击;
 
3.2 CBC模式:
优点:
1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点:
1.不利于并行计算;
2.误差传递;
3.需要初始化向量IV
 
3.3 CFB模式:
 优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.误差传送:一个明文单元损坏影响多个单元;
3.唯一的IV;
 
3.4 OFB模式:
 优点:
1.隐藏了明文模式;
2.分组密码转化为流模式;
3.可以及时加密传送小于分组的数据;
缺点:
1.不利于并行计算;
2.对明文的主动攻击是可能的;
3.误差传送:一个明文单元损坏影响多个单元;
 
密文长度问题:便于猜测是那种加密方式www.cmd5.com 
MD5加密后密文的长度和待加密的明文长度无关,md5属于单向hash函数,单向hash函数就是不管输入如何,只生成固定长度的输出用同一种哈希算法计算的字符长度是固定的,而且是唯一的。只有16位和32位两种,且16位是能够从32位截取出来。MD5密分两种,一种为16位的,一种为32位的,也就是说加密后的密文长度不一样,如果是16位的加密后一个字符的长度变为16个,所有语言加密后应该是一样的
 

 

 

本篇内容简要介绍BASE64MD5SHAHMAC几种加密算法。     BASE64编码算法不算是真正的加密算法。     MD5SHAHMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 
BASE64  按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)  常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。 

通过java代码实现如下:

Java代码  收藏代码
  1. /** 
  2.  * BASE64解密 
  3.  *  
  4.  * @param key 
  5.  * @return 
  6.  * @throws Exception 
  7.  */  
  8. public static byte[] decryptBASE64(String key) throws Exception {  
  9.     return (new BASE64Decoder()).decodeBuffer(key);  
  10. }  
  11.   
  12. /** 
  13.  * BASE64加密 
  14.  *  
  15.  * @param key 
  16.  * @return 
  17.  * @throws Exception 
  18.  */  
  19. public static String encryptBASE64(byte[] key) throws Exception {  
  20.     return (new BASE64Encoder()).encodeBuffer(key);  
  21. }  

主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。
MD5 MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。
通过java代码实现如下:

Java代码  收藏代码
  1. /** 
  2.  * MD5加密 
  3.  *  
  4.  * @param data 
  5.  * @return 
  6.  * @throws Exception 
  7.  */  
  8. public static byte[] encryptMD5(byte[] data) throws Exception {  
  9.   
  10.     MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);  
  11.     md5.update(data);  
  12.   
  13.     return md5.digest();  
  14.   
  15. }  

通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。
SHA SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全。 

通过java代码实现如下:

Java代码  收藏代码
  1.     /** 
  2.      * SHA加密 
  3.      *  
  4.      * @param data 
  5.      * @return 
  6.      * @throws Exception 
  7.      */  
  8.     public static byte[] encryptSHA(byte[] data) throws Exception {  
  9.   
  10.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  11.         sha.update(data);  
  12.   
  13.         return sha.digest();  
  14.   
  15.     }  
  16. }  

HMAC HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。

通过java代码实现如下:

Java代码  收藏代码
  1. /** 
  2.  * 初始化HMAC密钥 
  3.  *  
  4.  * @return 
  5.  * @throws Exception 
  6.  */  
  7. public static String initMacKey() throws Exception {  
  8.     KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);  
  9.   
  10.     SecretKey secretKey = keyGenerator.generateKey();  
  11.     return encryptBASE64(secretKey.getEncoded());  
  12. }  
  13.   
  14. /** 
  15.  * HMAC加密 
  16.  *  
  17.  * @param data 
  18.  * @param key 
  19.  * @return 
  20.  * @throws Exception 
  21.  */  
  22. public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
  23.   
  24.     SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
  25.     Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
  26.     mac.init(secretKey);  
  27.   
  28.     return mac.doFinal(data);  
  29.   
  30. }  

给出一个完整类,如下:

Java代码  收藏代码
  1. import java.security.MessageDigest;  
  2.   
  3. import javax.crypto.KeyGenerator;  
  4. import javax.crypto.Mac;  
  5. import javax.crypto.SecretKey;  
  6.   
  7. import sun.misc.BASE64Decoder;  
  8. import sun.misc.BASE64Encoder;  
  9.   
  10. /** 
  11.  * 基础加密组件 
  12.  *  
  13.  * @author 梁栋 
  14.  * @version 1.0 
  15.  * @since 1.0 
  16.  */  
  17. public abstract class Coder {  
  18.     public static final String KEY_SHA = "SHA";  
  19.     public static final String KEY_MD5 = "MD5";  
  20.   
  21.     /** 
  22.      * MAC算法可选以下多种算法 
  23.      *  
  24.      * <pre> 
  25.      * HmacMD5  
  26.      * HmacSHA1  
  27.      * HmacSHA256  
  28.      * HmacSHA384  
  29.      * HmacSHA512 
  30.      * </pre> 
  31.      */  
  32.     public static final String KEY_MAC = "HmacMD5";  
  33.   
  34.     /** 
  35.      * BASE64解密 
  36.      *  
  37.      * @param key 
  38.      * @return 
  39.      * @throws Exception 
  40.      */  
  41.     public static byte[] decryptBASE64(String key) throws Exception {  
  42.         return (new BASE64Decoder()).decodeBuffer(key);  
  43.     }  
  44.   
  45.     /** 
  46.      * BASE64加密 
  47.      *  
  48.      * @param key 
  49.      * @return 
  50.      * @throws Exception 
  51.      */  
  52.     public static String encryptBASE64(byte[] key) throws Exception {  
  53.         return (new BASE64Encoder()).encodeBuffer(key);  
  54.     }  
  55.   
  56.     /** 
  57.      * MD5加密 
  58.      *  
  59.      * @param data 
  60.      * @return 
  61.      * @throws Exception 
  62.      */  
  63.     public static byte[] encryptMD5(byte[] data) throws Exception {  
  64.   
  65.         MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);  
  66.         md5.update(data);  
  67.   
  68.         return md5.digest();  
  69.   
  70.     }  
  71.   
  72.     /** 
  73.      * SHA加密 
  74.      *  
  75.      * @param data 
  76.      * @return 
  77.      * @throws Exception 
  78.      */  
  79.     public static byte[] encryptSHA(byte[] data) throws Exception {  
  80.   
  81.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  82.         sha.update(data);  
  83.   
  84.         return sha.digest();  
  85.   
  86.     }  
  87.   
  88.     /** 
  89.      * 初始化HMAC密钥 
  90.      *  
  91.      * @return 
  92.      * @throws Exception 
  93.      */  
  94.     public static String initMacKey() throws Exception {  
  95.         KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);  
  96.   
  97.         SecretKey secretKey = keyGenerator.generateKey();  
  98.         return encryptBASE64(secretKey.getEncoded());  
  99.     }  
  100.   
  101.     /** 
  102.      * HMAC加密 
  103.      *  
  104.      * @param data 
  105.      * @param key 
  106.      * @return 
  107.      * @throws Exception 
  108.      */  
  109.     public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
  110.   
  111.         SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
  112.         Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
  113.         mac.init(secretKey);  
  114.   
  115.         return mac.doFinal(data);  
  116.   
  117.     }  
  118. }  

再给出一个测试类:

Java代码  收藏代码
  1. import static org.junit.Assert.*;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. /** 
  6.  *  
  7.  * @author 梁栋 
  8.  * @version 1.0 
  9.  * @since 1.0 
  10.  */  
  11. public class CoderTest {  
  12.   
  13.     @Test  
  14.     public void test() throws Exception {  
  15.         String inputStr = "简单加密";  
  16.         System.err.println("原文:/n" + inputStr);  
  17.   
  18.         byte[] inputData = inputStr.getBytes();  
  19.         String code = Coder.encryptBASE64(inputData);  
  20.   
  21.         System.err.println("BASE64加密后:/n" + code);  
  22.   
  23.         byte[] output = Coder.decryptBASE64(code);  
  24.   
  25.         String outputStr = new String(output);  
  26.   
  27.         System.err.println("BASE64解密后:/n" + outputStr);  
  28.   
  29.         // 验证BASE64加密解密一致性  
  30.         assertEquals(inputStr, outputStr);  
  31.   
  32.         // 验证MD5对于同一内容加密是否一致  
  33.         assertArrayEquals(Coder.encryptMD5(inputData), Coder  
  34.                 .encryptMD5(inputData));  
  35.   
  36.         // 验证SHA对于同一内容加密是否一致  
  37.         assertArrayEquals(Coder.encryptSHA(inputData), Coder  
  38.                 .encryptSHA(inputData));  
  39.   
  40.         String key = Coder.initMacKey();  
  41.         System.err.println("Mac密钥:/n" + key);  
  42.   
  43.         // 验证HMAC对于同一内容,同一密钥加密是否一致  
  44.         assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(  
  45.                 inputData, key));  
  46.   
  47.         BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));  
  48.         System.err.println("MD5:/n" + md5.toString(16));  
  49.   
  50.         BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));  
  51.         System.err.println("SHA:/n" + sha.toString(32));  
  52.   
  53.         BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));  
  54.         System.err.println("HMAC:/n" + mac.toString(16));  
  55.     }  
  56. }  

控制台输出:

Console代码  收藏代码
  1. 原文:  
  2. 简单加密  
  3. BASE64加密后:  
  4. 566A5Y2V5Yqg5a+G  
  5.   
  6. BASE64解密后:  
  7. 简单加密  
  8. Mac密钥:  
  9. uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke  
  10. pBIpkd7QHg==  
  11.   
  12. MD5:  
  13. -550b4d90349ad4629462113e7934de56  
  14. SHA:  
  15. 91k9vo7p400cjkgfhjh0ia9qthsjagfn  
  16. HMAC:  
  17. 2287d192387e95694bdbba2fa941009a  

    BASE64的加密解密是双向的,可以求反解。     MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。      单向加密的用途主要是为了校验数据在传输过程中是否被修改。

 

HMAC

一,概述

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;HMAC还引人了一个散列函数H,对消息进行 加密,进一步确保消息鉴别的安全性和有效性

本文档阐述了一种使用散列函数加密的消息验证机制——散列消息鉴别码
 HMAC。HMAC通过捆绑一个共享密钥可以使用任何迭代的可用于加密的散列
 函数。例如:MD5, SHA—1。这种加密机制的强度取决于所用散列函数的特性。

 

二,原理

基于散列函数的消息认证码。它需要一个加密用散列函数(表示为H,可以是MD5或者SHA-1)和一个密钥K用以计算消息认证码。

计算HMAC需要一个散列函数hash(可以是md5或者sha-1)和一个密钥key。用L表示hash函数输出字符串长(md5是16),用B表示数据块的长度(md5和sha-1的分割数据块长都是64)。密钥key的长度可以小于等于数据块长B,如果大于数据块长度,可以使用hash函数对key进行转换,结果就是一个L长的key。

然后创建两个B长的不同字符串:

innerpad = 长度为B的 0×36

outterpad = 长度为B的 0×5C

计算输入字符串str的HMAC:

hash(key ^ outterpad, hash(key ^ innerpad, str))

 

三,应用:

hmac主要应用在身份验证中,它的使用方法是这样的:

1. 客户端发出登录请求(假设是浏览器的GET请求)

2. 服务器返回一个随机值,并在会话中记录这个随机值

3. 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器

4. 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法

在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的hmac结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无获取用户密码的可能性,随机值的引入使hmac只在当前会话中有效,大大增强了安全性和实用性。大多数的语言都实现了hmac算法,比如php的mhash、python的hmac.py、java的MessageDigest类,在web验证中使用hmac也是可行的,用js进行md5运算的速度也是比较快的。

 

 

 

HMAC算法

 

(本文内容整理自网络文章) Message Authentication Code (MAC)消息鉴别码 •Similar to message digest/与消息摘要相似 •In addition, also involves encryption/ 另外,涉及加密 •Sender and receiver must know a shared secret key/ 发送方和接收方必须知道共享密钥 •可确认消息未被修改 •可确认消息是由发送端发送 •传统上构造MAC基于分组密码,但近年来研究构造MAC的兴趣已转移到杂凑函数 密码杂凑函数(如MD5、SHA)的软件实现快于分组密码(如DES)的软件实现; 密码杂凑函数的库代码来源广泛; 密码杂凑函数没有出口限制,而分组密码即使用于MAC也有出口限制。

Hash-based Message Authentication Code (HMAC) •involving a cryptographic hash function in combination with a secret cryptographic key. 结合了散列函数和密钥。 •As with any MAC, it may be used to simultaneously verify both the data integrity and the authenticity of a message. 可确认消息未被修改,可确认消息是由发送端发送 •Any cryptographic hash function, such as MD5 or SHA-1, may be used in the calculation of an HMAC;任何散列函数都可以用于计算HMAC
HMAC的定义 定义HMAC需要一个加密用散列函数(表示为H)和一个密钥K。 我们假设H是一个将数据块用一个基本的迭代压缩函数来加密的散列函数。 我们用B来表示数据块的字长。(以上说提到的散列函数的分割数据块字长B=64), 用L来表示散列函数的输出数据字长(MD5中L=16(128位),SHA—1中L=20(160位))。 鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。 应用程序中使用的密钥长度若是比B大,则首先用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。 一般情况下,推荐的最小密钥K长度是L个字长。(与H的输出数据长度相等)。
我们将定义两个固定且不同的字符串ipad,opad: (‘i','o'标志内部与外部) ipad = the byte 0x36 repeated B times opad = the byte 0x5C repeated B times. 计算‘text'的HMAC: H( K XOR opad, H(K XOR ipad, text)) 即为以下步骤:
(1) 在密钥K后面添加0来创建一个子长为B的字符串。 (例如,如果K的字长是20字节,B=64字节,则K后会加入44个零字节0x00) (2) 将上一步生成的B字长的字符串与ipad做异或运算。 (3) 将数据流text填充至第二步的结果字符串中。 (4) 用H作用于第三步生成的数据流。 (5) 将第一步生成的B字长字符串与opad做异或运算。 (6) 再将第四步的结果填充进第五步的结果中。 (7) 用H作用于第六步生成的数据流,输出最终结果
伪代码:

  1. function hmac (key, message)  
  2.     if (length(key) > blocksize) then  
  3.         key = hash(key) // keys longer than blocksize are shortened  
  4.     end if  
  5.     if (length(key) < blocksize) then  
  6.         key = key ∥ [0x00 * (blocksize - length(key))] // keys shorter than blocksize are zero-padded ('∥' is concatenation)  
  7.     end if  
  8.      
  9.     o_key_pad = [0x5c * blocksize] XOR key // Where blocksize is that of the underlying hash function  
  10.     i_key_pad = [0x36 * blocksize] XOR key  
  11.      
  12.     return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where '∥' is concatenation  
  13. end function  

 

密钥 用于HMAC的密钥可以是任意长度(比B长的密钥将首先被H处理)。 但当密钥长度小于L时的情况时非常令人失望的,因为这样将降低函数的安全强度。 长度大于L的密钥是可以接受的,但是额外的长度并不能显著的提高函数的安全强度。 密钥必须随机选取(或使用强大的基于随机种子的伪随机生成方法),并且要周期性的更新。 (目前的攻击没有指出一个有效的更换密钥的频率,因为那些攻击实际上并不可行。然而,周期性更新密钥是一个对付函数和密钥所存在的潜在缺陷的基本的安全措施,并可以降低泄漏密钥带来的危害。)

HMAC的典型应用

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中,认证流程如下: (1) 先由客户端向服务器发出一个验证请求。  (2) 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)。  (3) 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。  (4) 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户 。
SHA算法参数 *SHA-2是一个系列包括SHA-224,SHA-256,SHA-384和SHA-512

演算法輸出雜湊值長度 (bits)中繼雜湊值長度 (bits)資料區塊長度 (bits)最大輸入訊息長度 (bits)一個Word長度 (bits)迴圈次數使用到的運算子碰撞攻擊
SHA-0 160 160 512 264 − 1 32 80 +,and,or,xor,rotl
SHA-1 160 160 512 264 − 1 32 80 +,and,or,xor,rotl 存在263的攻擊
SHA-256/224 256/224 256 512 264 − 1 32 64 +,and,or,xor,shr,rotr 尚未出現
SHA-512/384 512/384 512 1024 2128 − 1 64 80 +,and,or,xor,shr,rotr 尚未出

 

HMAC算法安全性浅析

HMAC-SHA1是一种安全的基于加密hash函数和共享密钥的消息认证协议.它可以有效地防止数据在传输过程中被截获和篡改,维护了数据的完整性、可靠性和安全性.HMAC-SHA1消息认证机制的成功在于一个加密的hash函数、一个加密的随机密钥和一个安全的密钥交换机制.本文从HMAC和SHA1算法的概念入手,提出了一个基于SHA1算法的消息认证机制

 

 

消息摘要算法-MAC算法系列:

一、简述

  mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥。因此MAC算法也经常被称作HMAC算法。关于hmac算法的详情可以参看RFC 2104(http://www.ietf.org/rfc/rfc2104.txt),这里包含了HmacMD5算法的C语言实现。

  这里需要说明的是经过mac算法得到的摘要值也可以使用十六进制编码表示,其摘要值得长度与实现算法的摘要值长度相同。例如 HmacSHA算法得到的摘要长度就是SHA1算法得到的摘要长度,都是160位二进制数,换算成十六进制的编码为40位。

 

 

二、MAC系列算法支持表

 

算法 摘要长度 备注
HmacMD5 128 JAVA6实现
HmacSHA1 160 JAVA6实现
HmacSHA256 256 JAVA6实现
HmacSHA384 384 JAVA6实现
HmacSHA512 512 JAVA6实现
HmacMD2 128 BouncyCastle实现
HmacMD4 128 BouncyCastle实现
HmacSHA224 224 BouncyCastle实现
posted @ 2014-06-18 20:46  Agoly  阅读(4146)  评论(0编辑  收藏  举报