美国上市公司,专注Java培训22年

Java基础—数据摘要算法解析


数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名、数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密。数据摘要算法也被称为哈希(Hash)算法、散列算法。今天,达内java培训(java.tedu.cn)专家就带大家学习一下Java中的摘要算法。

项目结构如下:

java项目结构 

SHA算法

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。

一、HuhxSHA.java

  • package com.huhx.md;
  • import java.security.MessageDigest;
  • import org.apache.commons.codec.binary.Hex;
  • import org.apache.commons.codec.digest.DigestUtils;
  • import org.bouncycastle.crypto.Digest;
  • import org.bouncycastle.crypto.digests.SHA1Digest;
  • import org.junit.Test;
  • /**
  •  * wirter: huhx
  •  */
  • public class HuhxSHA {
  •     private static String src = "#/huhx";
  •     // jdk版本的sha算法
  •     @Test
  •     public void jdkSHA1() {
  •         try {
  •             MessageDigest messageDigest = MessageDigest.getInstance("SHA");
  •             messageDigest.update(src.getBytes());
  •             byte[] shaBytes = messageDigest.digest();
  •             System.out.println("jdk SHA 1: " + Hex.encodeHexString(shaBytes));
  •         } catch (Exception e) {
  •             e.printStackTrace();
  •         }
  •     }
  •     
  •     // commons-codec的sha算法
  •     @Test
  •     public void bcSHA1() {
  •         Digest digest = new SHA1Digest();
  •         digest.update(src.getBytes(), 0, src.length());
  •         
  •         byte[] shaBytes = new byte[digest.getDigestSize()];
  •         digest.doFinal(shaBytes, 0);
  •         System.out.println("bc SHA 1: " + org.bouncycastle.util.encoders.Hex.toHexString(shaBytes));
  •     }
  •     
  •     // bcprov的sha算法
  •     @Test
  •     public void ccSHA1() {
  •         System.out.println("cc SHA 1: " + DigestUtils.sha1Hex(src.getBytes()));
  •     }
  • }

二、 运行结果如下:

jdk SHA 1: 14ed5f04b940042df8dfcd5e60dc331dfddac16f

bc SHA 1: 14ed5f04b940042df8dfcd5e60dc331dfddac16f

cc SHA 1: 14ed5f04b940042df8dfcd5e60dc331dfddac16f

MD算法

MD2

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

MD4

为了加强算法的安全性,Rivest在1990年又开发出MD4算法。MD4算法同样需要填补信息以确保信息的比特位长度减去448后能被512整除(信息比特位长度mod 512 = 448)。然后,一个以64位二进制表示的信息的最初长度被添加进来。信息被处理成512位damg?rd/merkle迭代结构的区块,而且每个区块要通过三个不同步骤的处理。Den boer和Bosselaers以及其他人很快的发现了攻击MD4版本中第一步和第三步的漏洞。Dobbertin向大家演示了如何利用一部普通的个人电脑在几分钟内找到MD4完整版本中的冲突(这个冲突实际上是一种漏洞,它将导致对不同的内容进行加密却可能得到相同的加密后结果)。毫无疑问,MD4就此被淘汰掉了。尽管MD4算法在安全上有个这么大的漏洞,但它对在其后才被开发出来的好几种信息安全加密算法的出现却有着不可忽视的引导作用。

MD5

1991年,Rivest开发出技术上更为趋近成熟的md5算法。它在MD4的基础上增加了"安全-带子"(safety-belts)的概念。虽然MD5比MD4复杂度大一些,但却更为安全。这个算法很明显的由四个和MD4设计有少许不同的步骤组成。在MD5算法中,信息-摘要的大小和填充的必要条件与MD4完全相同。Den boer和Bosselaers曾发现MD5算法中的假冲突(pseudo-collisions),但除此之外就没有其他被发现的加密后结果了。

一、HuhxMD.java

  • package com.huhx.md;
  • import java.security.MessageDigest;
  • import java.security.Security;
  • import org.apache.commons.codec.digest.DigestUtils;
  • import org.bouncycastle.crypto.Digest;
  • import org.bouncycastle.crypto.digests.MD5Digest;
  • import org.bouncycastle.jce.provider.BouncyCastleProvider;
  • import org.bouncycastle.util.encoders.Hex;
  • import org.junit.Test;
  • public class HuhxMD {
  •     private static String src = "#/huhx";
  •     @Test
  •     public void jdkMD5() {
  •         try {
  •             MessageDigest messageDigest = MessageDigest.getInstance("MD5");
  •             byte[] mdBytes = messageDigest.digest(src.getBytes());
  •             System.out.println("md5 decode: " + Hex.toHexString(mdBytes));
  •         } catch (Exception e) {
  •             e.printStackTrace();
  •         }
  •     }
  •     @Test
  •     public void jdkMD2() {
  •         try {
  •             MessageDigest messageDigest = MessageDigest.getInstance("MD2");
  •             byte[] mdBytes = messageDigest.digest(src.getBytes());
  •             System.out.println("md2 decode: " + Hex.toHexString(mdBytes));
  •         } catch (Exception e) {
  •             e.printStackTrace();
  •         }
  •     }
  •     @Test
  •     public void bcmMD4() {
  •         // Digest digest = new MD4Digest();
  •         // digest.update(src.getBytes(), 0, src.length());
  •         // byte[] mdBytes = new byte[digest.getDigestSize()];
  •         // digest.doFinal(mdBytes, 0);
  •         // System.out.println("md4 decode: " + Hex.toHexString(mdBytes));
  •         Security.addProvider(new BouncyCastleProvider());
  •         try {
  •             MessageDigest messageDigest = MessageDigest.getInstance("MD4");
  •             byte[] mdBytes = messageDigest.digest(src.getBytes());
  •             System.out.println("md4 decode: " + Hex.toHexString(mdBytes));
  •         } catch (Exception e) {
  •             e.printStackTrace();
  •         }
  •     }
  •     //
  •     @Test
  •     public void bcmMD5() {
  •         Digest digest = new MD5Digest();
  •         digest.update(src.getBytes(), 0, src.length());
  •         byte[] mdBytes = new byte[digest.getDigestSize()];
  •         digest.doFinal(mdBytes, 0);
  •         System.out.println("md5 decode: " + Hex.toHexString(mdBytes));
  •     }
  •     //
  •     @Test
  •     public void ccMD5() {
  •         String md5String = DigestUtils.md5Hex(src.getBytes());
  •         System.out.println("common md5: " + md5String);
  •     }
  • }

二、 运行结果如下:

md4 decode: b402321e9a067da3df0c36c8315f8e38

md5 decode: f121bf5f7491466ae75e056f686c4462

md2 decode: 42b6b066b1273470f9aad644cede7644

md5 decode: f121bf5f7491466ae75e056f686c4462

common md5: f121bf5f7491466ae75e056f686c4462

MAC算法

MAC算法(Message Authentication Codes)带秘密密钥的Hash函数:消息的散列值由只有通信双方知道的秘密密钥K来控制。此时Hash值称作MAC。

MAC算法原理(以直联银联pos和POS中心通讯为例)。

将欲发送给POS中心的消息中,从消息类型(MTI)到63域之间的部分构成MAC ELEMEMENT BLOCK(MAB)。

对MAB,按每8个字节做异或(不管信息中的字符格式),如果最后不满8个字节,则添加“0X00”。

一、HuhxMAC.java
  • package com.huhx.md;
  • import javax.crypto.KeyGenerator;
  • import javax.crypto.Mac;
  • import javax.crypto.SecretKey;
  • import javax.crypto.spec.SecretKeySpec;
  • import org.bouncycastle.crypto.digests.MD5Digest;
  • import org.bouncycastle.crypto.macs.HMac;
  • import org.bouncycastle.crypto.params.KeyParameter;
  • import org.bouncycastle.util.encoders.Hex;
  • import org.junit.Test;
  • public class HuhxMAC {
  •     private static String src = "#/huhx";
  •     private static String decodeKey = "bbbbbbbbbb";
  •     @Test
  •     public void jdkHmacMD5() {
  •         try {
  •             //初始化KeyGenerator
  •             KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
  •             //产生密钥
  •             SecretKey secretKey = keyGenerator.generateKey();
  •             //获得密钥
  •             // byte[] keyBytes = secretKey.getEncoded();
  •             byte[] keyBytes = org.apache.commons.codec.binary.Hex.decodeHex(decodeKey.toCharArray());
  •             //还原密钥
  •             SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "HmacMD5");
  •             //实例化MAC
  •             Mac mac = Mac.getInstance(secretKeySpec.getAlgorithm());
  •             //初始化Mac
  •             mac.init(secretKeySpec);
  •             //执行摘要
  •             byte[] result = mac.doFinal(src.getBytes());
  •             System.out.println("jdk mac: " + Hex.toHexString(result));
  •         } catch (Exception e) {
  •             // TODO Auto-generated catch block
  •             e.printStackTrace();
  •         }
  •     }
  •     @Test
  •     public void bcHmacMD5() {
  •         HMac hMac = new HMac(new MD5Digest());
  •         hMac.init(new KeyParameter(Hex.decode(decodeKey)));
  •         hMac.update(src.getBytes(), 0, src.length());
  •         byte[] hMacBytes = new byte[hMac.getMacSize()];
  •         hMac.doFinal(hMacBytes, 0);
  •         System.out.println("bc mac: " + Hex.toHexString(hMacBytes));
  •     }
  • }

二、 运行结果如下:

bc mac: 3bf59d550b1e0d6cee15e015870029f9

jdk mac: 3bf59d550b1e0d6cee15e015870029f9

如何更好的掌握数据摘要算法?Java程序员需要的核心技术有哪些?零基础学java能学会吗?达内java培训(java.tedu.cn)专家提醒大家,如果你还有这些疑问,欢迎关注“达内java大数据培训”微信公众号,报名参加6月java免费训练营,众多一线高手在等你哦。


【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!

Java开发高端课程免费试学

大咖讲师+项目实战全面提升你的职场竞争力

  • 海量实战教程
  • 1V1答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • eclipse怎么建立Java项目?
    eclipse怎么建立Java项目?
    eclipse怎么建立Java项目?在使用Eclipse建立Java项目时,可以遵循以下步骤: 详情>>

    2024-05-10

  • Java关键词汇总-Java关键字有哪些及其作用?
    Java关键词汇总-Java关键字有哪些及其作用?
    Java关键词汇总-Java关键字有哪些及其作用?Java语言中的关键字(Keywords)是Java编程语言的核心组成部分,它们具有特定的意义,并被用于表示基本数据类型、控制语句、访问权限等。Java关键字总数大约有50个左右,下面列出了一些常用的Java关键字及其作用: 详情>>

    2024-04-08

  • Java编程工具用哪个最好
    Java编程工具用哪个最好
    Java编程工具用哪个最好?Java编程工具的选择取决于个人的偏好、项目需求和开发环境。以下是一些常用的Java编程工具: 详情>>

    2024-04-03

  • 好用的Java编写软件
    好用的Java编写软件
    Java是一种广泛使用的编程语言,因其跨平台、安全性和稳定性而受到许多开发者的喜爱。Java被用于开发各种类型的软件,从桌面应用程序到企业级服务器端应用程序。以下是一些常见的、用Java编写的软件示例: 详情>>

    2024-04-02

  • Java开班时间

    收起