密码学 ~ 消息摘要

消息摘要

消息摘要(Message Digest)又称为数字摘要(Digital Digest)
它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生
使用数字摘要生成的值是不可以篡改的,为了保证文件或者值的安全

特点

无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。
只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出
消息摘要是单向、不可逆的

例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息最终有160比特位的输出

常见的加密方式

  1. MD5
  2. SHA1
  3. SHA256
  4. SHA512

详解加密方式

MD5加密

message-digest algorithm 5(简称MD5),信息-摘要算法
底层采用的是散列哈希算法, 对一段信息产生信息摘要,防止被篡改,不算是加密算法,而是摘要算法
无论是多长的输入,md5都会输出长度为128bits(16字节)的哈希值

代码案例:

package com.example.password_discipline.utils;

import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5
 */
public class MD5 {


	/**
	 * 获取MD5消息摘要
	 * 
	 * @param data
	 *            源数据
	 * @return MD5消息摘要
	 */
	public static byte[] getMD5(byte[] data) {
		byte[] md5 = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md5 = md.digest(data);
		} catch (Exception e) {
		}
		return md5;
	}

	/*
	 * MD5字符串
	 */
	public static String getMD5Str(String str) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			if (!StringUtils.isEmpty(str)) {
				messageDigest.update(str.getBytes("UTF-8"));
			}
		} catch (NoSuchAlgorithmException e) {
//			logger.error(e);
		} catch (UnsupportedEncodingException e) {
//			logger.error(e);
		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}
		return md5StrBuff.toString().toUpperCase();
	}
	
	/*
	 * MD5字符串
	 */
	public static String getMD5Str(String str, String charset) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			if (!StringUtils.isEmpty(str)) {
				messageDigest.update(str.getBytes(charset));
			}
		} catch (NoSuchAlgorithmException e) {

		} catch (UnsupportedEncodingException e) {

		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}
		return md5StrBuff.toString().toUpperCase();
	}
	
	/**
	 * 16位MD5方法 
	 * @param sourceStr
	 * @return
	 */
	public static String MD5_16(String sourceStr) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(sourceStr.getBytes());
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString().substring(8, 24);
            
        } catch (NoSuchAlgorithmException e) {

        }
        return result;
    }

	/*
	 * MD5字符串
	 */
	public static String getMD5Str(byte[] data) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");

			messageDigest.reset();

			messageDigest.update(data);
		} catch (NoSuchAlgorithmException e) {

		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}
		return md5StrBuff.toString().toUpperCase();
	}

	public static void main(String[] args){
		System.out.println(MD5.getMD5Str("123456"));
	}
}

在这里插入图片描述

SHA1算法 SHA256算法 SHA512算法

SHA1是一种密码散列函数,由美国国家安全局设计,主要适用于数字签名标准里面定义的数字签名算法。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。今天我们将讨论的是SHA1算法原理和流程。

入门代码,只需要将MD5换成SHA1

package com.example.password_discipline.digest;


import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.MessageDigest;

public class DigestHexDemo {
	public static void main(String[] args) throws Exception {
		String data = "aa";
		String algorithm = "MD5";
		DigestHexDemo.getDigest(data, algorithm);

		String sha1 = getDigest(data, "SHA-1");

		String sha256 = getDigest(data, "SHA-256");

		String sha512 = getDigest(data, "SHA-512");

	}




	public static String toHex(byte[] digest){
		StringBuilder sb = new StringBuilder();
		for (byte b : digest) {
			String temp = Integer.toHexString(b & 0xff);
			if(temp.length() == 1){
				sb.append("0" + temp);
			}else {
				sb.append(temp);
			}
		}
		return sb.toString();
	}

	/**
	 * 生成摘要
	 * @param data
	 * @param algorithm
	 * @return
	 * @throws Exception
	 */
	public static String getDigest(String data, String algorithm) throws Exception{
		MessageDigest instance = MessageDigest.getInstance(algorithm);
		byte[] dataBytes = instance.digest(data.getBytes());
		String digest = toHex(dataBytes);
		System.out.println("当前加密字符串:" + data + ", 加密方式:" + algorithm + ",加密摘要:" + digest);
		return digest;
	}
}

获取文件消息摘要

package com.example.password_discipline.digest;


import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.security.MessageDigest;

public class DigestHexDemo {
	public static void main(String[] args) throws Exception {
		String data = "aa";
		String algorithm = "MD5";
		DigestHexDemo.getDigest(data, algorithm);
		String sha1 = getDigestFile("D:\\work\\password_discipline\\src\\test\\java\\com\\example\\password_discipline\\digest\\DigestHexDemo.zip", "SHA-1");
		System.out.println(sha1);

		String sha512 = getDigestFile("D:\\work\\password_discipline\\src\\test\\java\\com\\example\\password_discipline\\digest\\DigestHexDemo.zip", "SHA-512");
		System.out.println(sha512);
	}

	private static String getDigestFile(String filePath, String algorithm) throws Exception{
		FileInputStream fis = new FileInputStream(filePath);
		int len;
		byte[] buffer = new byte[1024];
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while ( (len =  fis.read(buffer))!=-1){
			baos.write(buffer,0,len);
		}
		// 获取消息摘要对象
		MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
		// 获取消息摘要
		byte[] digest = messageDigest.digest(baos.toByteArray());
		System.out.println("密文的字节长度:"+digest.length);
		return toHex(digest);
	}


	public static String toHex(byte[] digest){
		StringBuilder sb = new StringBuilder();
		for (byte b : digest) {
			String temp = Integer.toHexString(b & 0xff);
			if(temp.length() == 1){
				sb.append("0" + temp);
			}else {
				sb.append(temp);
			}
		}
		return sb.toString();
	}

	/**
	 * 生成摘要
	 * @param data
	 * @param algorithm
	 * @return
	 * @throws Exception
	 */
	public static String getDigest(String data, String algorithm) throws Exception{
		MessageDigest instance = MessageDigest.getInstance(algorithm);
		byte[] dataBytes = instance.digest(data.getBytes());
		String digest = toHex(dataBytes);
		System.out.println("当前加密字符串:" + data + ", 加密方式:" + algorithm + ",加密摘要:" + digest);
		return digest;
	}
}

运行程序 ,获取 sha-1 和 sha-512 的值
在这里插入图片描述
使用 sha-1 算法,可以实现秒传功能,不管咱们如何修改文件的名字,最后得到的值是一样的
在这里插入图片描述
运行程序 ,获取 sha-1 和 sha-512 的值
在这里插入图片描述
如果原文修改了,那么sha-1值 就会不一样
在这里插入图片描述
运行结果:
在这里插入图片描述

总结

  • MD5算法 : 摘要结果16个字节, 转16进制后32个字节
  • SHA1算法 : 摘要结果20个字节, 转16进制后40个字节
    SHA256算法 : 摘要结果32个字节, 转16进制后64个字节
    SHA512算法 : 摘要结果64个字节, 转16进制后128个字节.

推荐同系列文章

keytool openssl : https://blog.csdn.net/xiaozhegaa/article/details/109602118
密码学 ~ 数字签名: https://blog.csdn.net/xiaozhegaa/article/details/109601966
密码学 ~ 非对称加密 RSA ECC: https://blog.csdn.net/xiaozhegaa/article/details/109601632
密码学 ~ 消息摘要: https://blog.csdn.net/xiaozhegaa/article/details/109601148
对称加密、DES加解密、AES加解密、Base64加解密: https://blog.csdn.net/xiaozhegaa/article/details/109595399

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值