走进密码学 - 消息摘要(一) 2020-10-19 22:24 消息摘要,又称为数字摘要 许多人把md5之类的算法叫做加密算法,常见的口误是“md5加密算法”,其实md5算法不是加密算法,她不是用来加密的,她是一种消息摘要算法。 根据字面意思我们可以理解:消息摘要,关键词消息,摘要。消息就是我们说的“数据”,或“原文”。比如我有要传输的数据data,或者用户的账号username,这些数据都可以称为消息。摘要就是我们平常看的书、文章里的摘要,一篇文章通常有一小段摘要,位于题目下面,文章内容上面。无论这篇文章多长或多短,这段摘要通常就是那么些文字,不长不短。放在这里理解,就是我们消息的摘要。根据前面的分析不难揣摩出消息摘要的功能:无论多大或多小或各式各样的原数据,生成固定长度的摘要内容。 **特点:** 一段数据在一个算法下对应一个固定的摘要。 无论原数据发生多么小的改变,生成的摘要都会发生变化。 即:**只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出,消息摘要是单向、不可逆的。** (具体底层原理日后我会继续出文章来讲解) 常见算法: MD5算法生成的摘要是16byte的数组(1个字节=8位),即16*8 = 128个比特位 SHA-1 20byte 160bit SHA-256 32byte 256bit SHA-512 64byte 512bit 获取数字摘要: ```java package EncrptDemo; import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @author: HanXu * on 2020/10/19 * Class description: 消息摘要算法 * MD5 SHA-1 SHA-256 SHA-512 */ public class DigestDemo { public static void main(String[] args) throws Base64DecodingException { String data = "我是韩旭"; //摘要算法不区分大小写 String algorithm = "MD5"; String digest = getDigest(data, algorithm); System.out.println(digest); // 4124bc0a9335c27f086f24ba207a4912 System.out.println(digest.length()); // 32 algorithm = "sha-1"; digest = getDigest(data, algorithm); System.out.println(digest); // e0c9035898dd52fc65c41454cec9c4d2611bfb37 System.out.println(digest.length()); // 40 algorithm = "SHA-256"; digest = getDigest(data, algorithm); System.out.println(digest); // 961b6dd3ede3cb8ecbaacbd68de040cd78eb2ed5889130cceb4c49268ea4d506 System.out.println(digest.length()); // 64 algorithm = "SHA-512"; digest = getDigest(data, algorithm); System.out.println(digest); // f6c5600ed1dbdcfdf829081f5417dccbbd2b9288e0b427e65c8cf67e274b69009cd142475e15304f599f429f260a661b5df4de26746459a3cef7f32006e5d1c1 System.out.println(digest.length()); // 128 String digestFile = getDigestFile("E:\\apache-tomcat-8.5.59.zip", algorithm); System.out.println(digestFile); //e1a099b76ae5db8ee92c44de8078312b8f6cc9fda53811682c776725255410fed31de6fe476933935cdac06793aef9c97d0c0e0d74ee4a1b4c4e1cc682b060af //e1a099b76ae5db8ee92c44de8078312b8f6cc9fda53811682c776725255410fed31de6fe476933935cdac06793aef9c97d0c0e0d74ee4a1b4c4e1cc682b060af } /** * 获取文件的消息摘要 * @param filePath * @param algorithm * @return * @throws Exception */ private static String getDigestFile(String filePath, String algorithm) { FileInputStream fis = null; try { fis = new FileInputStream(filePath); } catch (FileNotFoundException e) { e.printStackTrace(); System.err.println("文件路径不存在"); } int len; byte[] buffer = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { while ( (len = fis.read(buffer))!=-1){ baos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } // 获取消息摘要对象 MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); System.err.println("没有该摘要算法"); } // 获取消息摘要 byte[] digest = messageDigest.digest(baos.toByteArray()); System.out.println("生成摘要字节数组长度:"+digest.length); return toHex(digest); } /** * 获取摘要 * @param data 源数据 * @param algorithm 摘要算法 * @return */ private static String getDigest(String data, String algorithm) { MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); System.err.println("没有该摘要算法"); } //生成摘要 byte[] digestBytes = messageDigest.digest(data.getBytes()); System.out.println("生成摘要字节数组长度:" + digestBytes.length); //String encode = Base64.encode(digestBytes); //System.out.println(encode); // Base64编码输出 QSS8CpM1wn8IbyS6IHpJEg== return toHex(digestBytes); } /** * 转化为十六进制 * @param digestBytes 字节数组 * @return */ private static String toHex(byte[] digestBytes) { StringBuilder sb = new StringBuilder(); for (byte b : digestBytes) { String s = Integer.toHexString(b & 0xff); if (s.length() == 1) { s = "0" + s; } sb.append(s); } return sb.toString(); } } ``` --END--
发表评论