SHA:安全散列算法简析 附实例
前言
体能状态先于精神状态,习惯先于决心,聚焦先于喜好。
SHA算法简介
1.1概述
SHA(SecureHashAlgorithm,译作安全散列算法)是美国国家安全局(NSA)设计,美国国家标准与技术研究院(NIST)发布的一系列密码散列函数。正式名称为SHA的家族第一个成员发布于1993年。然而人们给它取了一个非正式的名称SHA-0以避免与它的后继者混淆。两年之后,SHA-1,第一个SHA的后继者发布了。另外还有四种变体,曾经发布以提升输出的范围和变更一些细微设计:SHA-224,SHA-256,SHA-384和SHA-512(这些有时候也被称做SHA-2)。
SHA家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,由美国国家安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布;是美国的政府标准。后四者有时并称为SHA-2。SHA-1在许多安全协定中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5(更早之前被广为使用的杂凑函数)的后继者。但SHA-1的安全性如今被密码学家严重质疑;虽然至今尚未出现对SHA-2有效的攻击,它的算法跟SHA-1基本上仍然相似;因此有些人开始发展其他替代的杂凑算法。
1.2SHA算法原理
SHA-1是一种数据加密算法,该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。
单向散列函数的安全性在于其产生散列值的操作过程具有较强的单向性。如果在输入序列中嵌入密码,那么任何人在不知道密码的情况下都不能产生正确的散列值,从而保证了其安全性。SHA将输入流按照每块512位(64个字节)进行分块,并产生20个字节的被称为信息认证代码或信息摘要的输出。
该算法输入报文的长度不限,产生的输出是一个160位的报文摘要。输入是按512位的分组进行处理的。SHA-1是不可逆的、防冲突,并具有良好的雪崩效应。
通过散列算法可实现数字签名实现,数字签名的原理是将要传送的明文通过一种函数运算(Hash)转换成报文摘要(不同的明文对应不同的报文摘要),报文摘要加密后与明文一起传送给接受方,接受方将接受的明文产生新的报文摘要与发送方的发来报文摘要解密比较,比较结果一致表示明文未被改动,如果不一致表示明文已被篡改。
1.3SHA算法应用
SHA算法主要用于被政府部门和私营业主用来处理敏感的信息。例如,支付机构,银行之间的数据传输,有的是使用SHA散列算计进行加密。
SHA安全散列算法
安全散列算法(英语:SecureHashAlgorithm,缩写为SHA)是一个密码散列函数家族.
和MD5类似,安全散列算法可以根据字符串生成一定长度的摘要信息,该摘要信息不可逆转,且不同的字符串的摘要信息相同的概率极低。
SHA家族
SHA有多个算法,有一些已经过时不再推荐使用,有一些是安全度很高的,但是会降低性能。
SHA1
对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。
不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要,(但会有1x10^48分之一的机率出现相同的消息摘要,一般使用时忽略)。
可以用于校验信息是否被篡改,比如数字证书的签名
已经不安全了,所以数字签名证书多用SHA256
SHA256
SHA256从功能上来说和SHA1类似,一般也用于信息摘要,算法使用的哈希值长度是256位
用于数字证书的签名,一般数据的签名,目前流行的安全散列算法
SHA384、SHA512
内容略,更安全,也更消耗性能,截止2019年8月20日,这两种算法都还没有大范围推荐使用,市面上推荐的是SHA256
安全性
目前而言,SHA1不安全了,SHA256还是安全的
但是从兼容性来说,很多系统依旧支持SHA1,但是最新的则会要求是SHA256
Java中的SHA
使用commons-codec
可以使用Apache提供的jar包commons-codec
Maven依赖如下
commons-codec commons-codec 1.10
代码举例
结果是字节数组,转化为16进制展示
Java
importorg.apache.commons.codec.digest.DigestUtils; publicclassShaTest{ publicstaticvoidmain(String[]args){ Stringstr="123"; Stringsha1HexStr=DigestUtils.sha1Hex(str.getBytes()); System.out.println("SHA1"+":"+sha1HexStr.length()+";"+sha1HexStr); Stringsha256HexStr=DigestUtils.sha256Hex(str.getBytes()); System.out.println("SHA256"+":"+sha256HexStr.length()+";"+sha256HexStr); Stringsha384HexStr=DigestUtils.sha384Hex(str.getBytes()); System.out.println("SHA384"+":"+sha384HexStr.length()+";"+sha384HexStr); Stringsha512HexStr=DigestUtils.sha512Hex(str.getBytes()); System.out.println("SHA512"+":"+sha512HexStr.length()+";"+sha512HexStr); } }
结果-使用16进制展示
SHA1:40;40bd001563085fc35165329ea1ff5c5ecbdbbeef
SHA256:64;a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
SHA384:96;9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f
SHA512:128;3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2
下面是其他网友的补充
java代码实现SHA算法
packagecn.mars.app.txn.wanglian; importjava.security.MessageDigest; importjava.security.NoSuchAlgorithmException; publicclassSha1Util{ /** *SHA1签名 *@paramparamStr要加签的字符串 *@return */ publicstaticStringSHA1(StringparamStr){ MessageDigestalg; Stringresult=""; Stringtmp=""; try{ alg=MessageDigest.getInstance("SHA-1"); alg.update(paramStr.getBytes()); byte[]bts=alg.digest(); for(inti=0;i经过加密后的字符串的个数是固定的:40
packagecom.enterise.test; publicclassSHA1{ privatefinalint[]abcde={0x67452301,0xefcdab89,0x98badcfe, 0x10325476,0xc3d2e1f0}; //摘要数据存储数组 privateint[]digestInt=newint[5]; //计算过程中的临时数据存储数组 privateint[]tmpData=newint[80]; // 测试 publicstaticvoidmain(String[]args){ Stringparam=""; System.out.println("加密前:"+param); System.out.println("length-->"+param.length()); Stringdigest=newSHA1().getDigestOfString(param.getBytes()); System.out.println("加密后:"+digest); System.out.println("length-->"+digest.length()); } //计算sha-1摘要 privateintprocess_input_bytes(byte[]bytedata){ //初试化常量 System.arraycopy(abcde,0,digestInt,0,abcde.length); //格式化输入字节数组,补10及长度数据 byte[]newbyte=byteArrayFormatData(bytedata); //获取数据摘要计算的数据单元个数 intMCount=newbyte.length/64; //循环对每个数据单元进行摘要计算 for(intpos=0;pos>8)&0xFF); byteh6=(byte)((N>>16)&0xFF); byteh5=(byte)((N>>24)&0xFF); byteh4=(byte)((N>>32)&0xFF); byteh3=(byte)((N>>40)&0xFF); byteh2=(byte)((N>>48)&0xFF); byteh1=(byte)(N>>56); newbyte[l++]=h1; newbyte[l++]=h2; newbyte[l++]=h3; newbyte[l++]=h4; newbyte[l++]=h5; newbyte[l++]=h6; newbyte[l++]=h7; newbyte[l++]=h8; returnnewbyte; } privateintf1(intx,inty,intz){ return(x&y)|(~x&z); } privateintf2(intx,inty,intz){ returnx^y^z; } privateintf3(intx,inty,intz){ return(x&y)|(x&z)|(y&z); } privateintf4(intx,inty){ return(x< >>(32-y); } // // 单元摘要计算函数 privatevoidencrypt(){ for(inti=16;i<=79;i++){ tmpData[i]=f4(tmpData[i-3]^tmpData[i-8]^tmpData[i-14] ^tmpData[i-16],1); } int[]tmpabcde=newint[5]; for(inti1=0;i1 >>24); byteData[i+1]=(byte)(intValue>>>16); byteData[i+2]=(byte)(intValue>>>8); byteData[i+3]=(byte)intValue; } //将字节转换为十六进制字符串 privatestaticStringbyteToHexString(byteib){ char[]Digit={'0','1','2','3','4','5','6','7','8','9','A', 'B','C','D','E','F'}; char[]ob=newchar[2]; ob[0]=Digit[(ib>>>4)&0X0F]; ob[1]=Digit[ib&0X0F]; Strings=newString(ob); returns; } //将字节数组转换为十六进制字符串 privatestaticStringbyteArrayToHexString(byte[]bytearray){ StringstrDigest=""; for(inti=0;i 到此这篇关于SHA:安全散列算法的文章就介绍到这了,更多相关SHA安全散列算法内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!