zoukankan      html  css  js  c++  java
  • HMAC简介及HMAC-SHA256实现Demo

    一、什么是HMAC

    HMAC是一种使用单向散列函数来构造消息认证码的方法,其中HMAC中的H就是Hash的意思。

    HMAC中所使用的单向散列函数并不仅限于一种,任何高强度的单向散列函数都可以被用于HMAC,如果将来设计出的新的单向散列函数,也同样可以使用。

    使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。

    二、HMAC的计算步骤

     

     1、密钥填充

    如果密钥比单向散列函数分组长度要短,就需要在末尾填充0,直到其长度达到单向散列函数的分组长度为止。

    如果密钥比分组长度要长,则要用单向散列函数求出密钥的散列值,然后将这个散列值用作HMAC的密钥。

    2、填充后的密钥与ipad的XOR

    将填充后的密钥与被称为ipad的比特序列进行XOR运算。ipad是将00110110这一比特序列不断循环反复直到达到分组长度所形成的比特序列,其中ipad的i是inner的意思。

    XOR运算所得到的值,就是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里将这个比特序列称为ipadkey。

    3、与消息组合

    随后,将ipadkey与消息组合,也就是将和密钥相关的比特序列(ipadkey)附加在消息的开头。

    4、计算散列值

    将3的结果输入单向散列函数,并计算出散列值。

    5、填充后的密钥与opad的XOR

    将填充后的密钥与被称为opad的比特序列进行XOR运算,opad是将01011100这一比特序列不断循环反复直到达到分组长度所形成的比特序列,其中opad的o是outer的意思。

    XOR运算所得到的结果也是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这里将这个比特序列称为opadkey。

    6、与散列值组合

    将4的散列值拼在opadkey后面。

    7、计算散列值

    将6的结果输入单向散列函数,并计算出散列值,这个散列值就是最终的MAC值。

    通过上述流程可以看出,最后得到的MAC值,一定是一个和输入的消息以及密钥都相关的长度固定的比特序列。

     三、HMAC应用

    HAMC主要应用在身份验证,服务器对访问者进行鉴权,流程如下图所示:

    https://upload-images.jianshu.io/upload_images/1546230-1699375397c0eb10.png?imageMogr2/auto-orient/

     四、HMAC-SHA256实现Demo

    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    public class Sha256_mac {
        public static String sha256_mac(String message,String key){
            String outPut= null;
            try{
                Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
                SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(),"HmacSHA256");
                sha256_HMAC.init(secret_key);
                byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
                outPut = byteArrayToHexString(bytes);
            }catch (Exception e){
                System.out.println("Error HmacSHA256========"+e.getMessage());
            }
            return outPut;
        }
        public static String byteArrayToHexString(byte[] b) {
            StringBuilder sb = new StringBuilder();
            String stmp;
            for (int n = 0; b != null && n < b.length; n++) {
                stmp = Integer.toHexString(b[n] & 0XFF);
                if (stmp.length() == 1)
                    sb.append('0');
                sb.append(stmp);
            }
            return sb.toString().toLowerCase();
        }
    
    }
  • 相关阅读:
    Day 50
    Spring Boot logging 配置及相关属性
    spring boot的项目名称问题
    spring boot的项目结构问题
    @RestController无法自动注入的问题
    mysql的模糊查询
    写点什么来为自己的过去和未来画个分隔符
    python学习随笔day2
    python学习随笔day1
    linux文件上传和下载
  • 原文地址:https://www.cnblogs.com/Eleven-Liu/p/12422114.html
Copyright © 2011-2022 走看看