消息摘要的编程使用(MD5、SHA、HMAC)

    xiaoxiao2021-03-25  54

    消息摘要的概念: 

             唯一对应一个消息或文本的固定长度的值,由一个单向Hash加密函数对消息进行作用而产生

     消息摘要的分类:

    (1)MD(Message Digest):消息摘要算法

    (2)SHA(Secure Hash Algorithm):安全散列算法

    (3)MAC(Message Authentication Code):消息认证码算法

    消息摘要的日常应用

        验证文件的完整性

    MD 算法的编程使用

        为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护,分为md2(128位),md5(128位),md2目前已被弃用。

    package com.cry.md5; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import com.cry.ByteToHexUtil; /** * md5消息摘要(用于检测文件的完整性) * @author zhangwx * */ public class MD5Util { /** * 字符串md5 * @param data * @return * @throws NoSuchAlgorithmException */ public static String encryptMD5(byte[] data,String type) throws NoSuchAlgorithmException{ MessageDigest md5 = MessageDigest.getInstance(type); md5.update(data); byte[] result = md5.digest(); //转为16进制 String str = ByteToHexUtil.bytesToHexString(result); return str; } /** * 文件消息摘要 * @param path * @return * @throws NoSuchAlgorithmException * @throws IOException */ public static String encryptMD5OfFile(String path,String type) throws NoSuchAlgorithmException, IOException{ FileInputStream in = new FileInputStream(new File(path)); DigestInputStream dis = new DigestInputStream(in, MessageDigest.getInstance(type)); byte[] buffer = new byte[1024]; int read = dis.read(buffer, 0, 1024); while (read != -1){ read = dis.read(buffer, 0, 1024); } MessageDigest md5 = dis.getMessageDigest(); String result = ByteToHexUtil.bytesToHexString(md5.digest()); return result; } public static void main(String[] args) throws NoSuchAlgorithmException, IOException { String str = "test md5"; System.out.println(MD5Util.encryptMD5(str.getBytes(),"MD5")); System.out.println(MD5Util.encryptMD5OfFile("D:/Installpackage/PieTTY 0.3.26.exe","MD5")); } }

    package com.cry; public class ByteToHexUtil { public static String bytesToHexString(byte[] src){ StringBuilder stringBuilder = new StringBuilder(""); if(src==null||src.length<=0){ return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } }

    SHA算法的编程使用

        安全哈希算法,主要适用于数字签名标准里面定义的数字签名算法,SHA-1(160位),SHA-256(256位),

    SHA-384(384位),SHA-512(512位),向上减少碰撞几率。

    package com.cry.sha; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import com.cry.ByteToHexUtil; public class SHAUtils { /** * sha安全消息摘要(相比md5更安全,其中SHA-256,SHA-384拥有更小的碰撞几率) * @param data * @param type * @return * @throws NoSuchAlgorithmException */ public static String encryptSHA(byte[] data,String type) throws NoSuchAlgorithmException{ MessageDigest sha = MessageDigest.getInstance(type); sha.update(data); //转16进制 String result = ByteToHexUtil.bytesToHexString(sha.digest()); return result; } public static void main(String[] args) throws NoSuchAlgorithmException { String str = "test sha"; System.out.println(str+">>>SHA-1>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA")); System.out.println(str+">>>SHA-256>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA-256")); System.out.println(str+">>>SHA-384>>>"+SHAUtils.encryptSHA(str.getBytes(), "SHA-384")); } }

    引言:单一MD或SHA算法缺点?

        摘要值容易被篡改!

    HMAC 算法的基本概念 

             结合了MD5和SHA算法的优势,同时用密钥对摘要加密,是一种更为安全的消息摘要算法

    package com.cry.hmac; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import com.cry.ByteToHexUtil; /** * 结合了MD5和SHA算法的优势,同时用密钥对摘要加密,是一种更为安全的消息摘要算法 * 秘钥只有发送方和接收方知道 * @author zhangwx * */ public class HMACUtils { /** * 生成秘钥 * @param type * @return * @throws NoSuchAlgorithmException */ public static byte[] getSecretKey(String type) throws NoSuchAlgorithmException{ //初始化KeyGenerator KeyGenerator keyGen = KeyGenerator.getInstance(type); //生成秘钥 SecretKey secretKey = keyGen.generateKey(); //转化为字节数组 byte[] key = secretKey.getEncoded(); return key; } /** * 消息摘要 * @param key * @param type * @return * @throws NoSuchAlgorithmException * @throws InvalidKeyException */ public static String encryptHmacMD5(byte[] key,String type) throws NoSuchAlgorithmException, InvalidKeyException{ //还原秘钥 SecretKey secretKey = new SecretKeySpec(key, type); //实例化Mac Mac mac = Mac.getInstance(type); //用秘钥初始化Mac mac.init(secretKey); //获取消息摘要 byte[] result = mac.doFinal(); String str = ByteToHexUtil.bytesToHexString(result); return str; } public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException { String type = "HmacMD5"; byte[] secretKey = HMACUtils.getSecretKey(type); System.out.println(HMACUtils.encryptHmacMD5(secretKey, type)); type = "HmacSHA1"; secretKey = HMACUtils.getSecretKey(type); System.out.println(HMACUtils.encryptHmacMD5(secretKey, type)); type = "HmacSHA256"; secretKey = HMACUtils.getSecretKey(type); System.out.println(HMACUtils.encryptHmacMD5(secretKey, type)); } }
    转载请注明原文地址: https://ju.6miu.com/read-36822.html

    最新回复(0)