JAVA计算摘要,MD5、SHA-1、SHA-256、SHA-512、HmacMD5、HmacSHA1 、HmacSHA256、HmacSHA512

摘要的作用?


1.保证数据的完整性:例如你发送一个100M的文件给你的B,但是你不知道B收到的是否是完整的文件;此时你首先使用摘要算法,如MD5,计算了一个固定长度的摘要,将这个摘要和文件一起发送给B,B接收完文件之后,同样使用MD5计算摘要,如果B计算的结果和你发送给他的摘要结果一致,说明B接收的文件是完整的。
2.数字签名:数字签名里面的签名都是使用摘要算法计算的,目前(2017年),数字签名的摘要算法已经使用SHA-256作为规范


JAVA如何产生摘要

JDK包含一个security包,这个包已经实现主流的摘要算法,没有特殊需求直接拿过来使用就好:(java.security.MessageDigest)
加密方式:MD5、SHA-1、SHA-256、SHA-512、HmacMD5、HmacSHA1 、HmacSHA256、HmacSHA512

public final class MessageDigestUtil {
    /**
     * 使用指定哈希算法计算摘要信息
     * @param content 内容
     * @param algorithm 哈希算法
     * @return 内容摘要
     */
    public static String getMD5Digest(String content,String algorithm){
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(content.getBytes("utf-8"));
            return bytesToHexString(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 将字节数组转换成16进制字符串
     * @param bytes 即将转换的数据
     * @return 16进制字符串
     */
    private static String bytesToHexString(byte[] bytes){
        StringBuffer sb = new StringBuffer(bytes.length);
        String temp = null;
        for (int i = 0;i< bytes.length;i++){
            temp = Integer.toHexString(0xFF & bytes[i]);
            if (temp.length() <2){
                sb.append(0);
            }
            sb.append(temp);
        }
        return sb.toString();
    }
}

调用:

MessageDigestUtil.getMD5Digest("test","sha-256");

输出:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

API调取

方法补充说明
getSHA1获得SHA1摘要
getSHA256获得SHA256摘要
getSHA512获得SHA512摘要
getHmacMD5获得HmacMD5摘要
getHmacSHA1获得HmacSHA1摘要
getHmacSHA256获得HmacSHA256摘要
getHmacSHA512获得HmacSHA512摘要
getPBKDF2默认迭代54次,产生32位密钥
getRandomSalt获得一个定长的盐

注意:

  • 不适用于SHA384等非2i 2^i2 长度的方法。如有需要,请重写toHex()方法
  • 默认加盐方式为"msg"+“salt”,如需自定义请重写addSalt方法
  • 精简版代码中只包含MD5相关算法,可以参照该方法填充其它数字摘要算法。参考此处:完整摘要算法工具类Java代码封装

精简版的JAVA代码

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.spec.KeySpec;

public class MDBuilder {

    // 散列算法
    public static String getMD5(String msg, String salt){
        return MDBuilder.buildMD(msg, "MD5", salt);
    }
    // 哈希算法
    public static String getHmacMD5(String msg, String key, String salt){
        return MDBuilder.buildHmacMD(msg, "HmacMD5", key, salt);
    }
    // 产生具体的编码
    private static String buildMD(String msg, String algs, String salt){
        String retult="";
        try{
            MessageDigest md = MessageDigest.getInstance(algs);
            byte[] buff = md.digest(addSalt(msg,salt).getBytes());
            retult  = toHex(buff);
        }catch (Exception e){
            e.printStackTrace();
        }
        return retult;
    }

    private static String buildHmacMD(String msg, String algs, String key, String salt) {
        String result="";
        try{
            SecretKey sk = new SecretKeySpec(key.getBytes(),algs);
            Mac mac = Mac.getInstance(algs);
            mac.init(sk);
            byte[] buff = mac.doFinal(addSalt(msg, salt).getBytes());
            result = toHex(buff);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    // 对盐的添加方式
    private static String addSalt(String msg, String salt){
        return msg+salt;
    }

    // 迭代散列
    private static final int PBKDF2_ITERATIONS = 54;
    private static final int HASH_BIT_SIZE  = 32 * 4;
    /** @link https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory */
    private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";

    public static String getPBKDF2(String msg, String salt, int iterations){
        String result="";
        try{
            KeySpec spec = new PBEKeySpec(msg.toCharArray(), salt.getBytes(), iterations, HASH_BIT_SIZE);
            SecretKeyFactory f = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
            result = toHex(f.generateSecret(spec).getEncoded());
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
    //将128位的二进制序列转为32位的16进制编码
    private static String toHex(byte[] bytes) {
        StringBuilder md5str = new StringBuilder();
        for (byte aByte : bytes) {
            int temp = aByte;
            if (temp < 0) temp += 256; // 0x8* 在经过toHexString转化时,会被转为ffffff8*,需要+256保证其正值
            if (temp < 16) md5str.append("0"); // 0x05 转化会变成 5,缺少一位0
            md5str.append(Integer.toHexString(temp));
        }
        return md5str.toString();
    }
	// 产生一个指定种子的Strong盐
    public static String getRandomSalt(int length, Long seed){
        String salt = "default";
        try{
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            if(seed!=null)random.setSeed(seed);
            byte[] bytes = new byte[length / 2];
            random.nextBytes(bytes);
            //将byte数组转换为16进制的字符串
            salt = DatatypeConverter.printHexBinary(bytes);
        }catch (Exception e){
            e.printStackTrace();
        }
        return salt;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于 Java 的 Mac 类实现 HMAC-MD5 算法的示例代码: ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class HmacMd5 { public static void main(String[] args) { String message = "Hello, world!"; String key = "secret"; String hmac = hmacMd5(message, key); System.out.println(hmac); } public static String hmacMd5(String message, String key) { try { // 创建 Mac 对象 Mac mac = Mac.getInstance("HmacMD5"); // 创建 SecretKeySpec 对象 SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "HmacMD5"); // 初始化 Mac 对象 mac.init(keySpec); // 计算 HMAC 值 byte[] hmacBytes = mac.doFinal(message.getBytes()); // 对 HMAC 值进行 Base64 编码 return Base64.getEncoder().encodeToString(hmacBytes); } catch (NoSuchAlgorithmException | InvalidKeyException e) { e.printStackTrace(); return null; } } } ``` 在示例代码中,我们通过调用 `hmacMd5` 方法来计算 HMAC-MD5 值。该方法接受两个参数:`message` 表示要计算 HMAC 值的消息,`key` 表示 HMAC 密钥。在方法内部,我们首先创建 Mac 对象,然后创建 SecretKeySpec 对象,并使用 HMAC 密钥初始化 Mac 对象。接着,我们调用 Mac 对象的 `doFinal` 方法来计算 HMAC 值,并将其转换为 Base64 编码的字符串返回。最后,在 `main` 方法中,我们演示了如何使用该方法来计算 HMAC-MD5 值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值