Message Authentication Code_消息认证码算法

本文深入探讨了MAC算法的原理与应用,包括消息认证码的概念、MAC函数的使用及安全性考量,重点介绍了HMAC的实现方法及其背后的数学原理。通过具体的案例展示了如何在实际场景中使用MAC算法确保消息的完整性和真实性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Message Authentication Code_消息认证码算法

内容来源于网络

部分内容摘自博客:http://blog.youkuaiyun.com/zzminer/article/details/8574287

 

MAC算法结合了MD5和SHA算法的优势,并加入密钥的支持,是一种更为安全的消息摘要算法。

MAC(Message Authentication Code,消息认证码算法)是含有密钥的散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加入了密钥。

MAC算法主要集合了MD和SHA两大系列消息摘要算法。MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384.HmacSHA512五种算法。

经过MAC算法得到的摘要值也可以使用十六进制编码表示,其摘要值长度与参与实现的摘要值长度相同。例如,HmacSHA1算法得到的摘要长度就是SHA1算法得到的摘要长度,都是160位二进制,换算成十六进制编码为40位。

 

MAC函数

170101_Zo2o_1469576.png

 

MAC(Message Authentication Code)

案例:

某公司对来自网络的欺诈性订单叫苦不迭。为了改变这种局面,公司分配给每位客户一个唯一的密钥。客户每下一个订单,均需要提供订单的MAC签名(用这个密钥计算得来)。因为公司有客户的密钥,所以自然能够验证此订单:1. 是否来自所声明的客户,2.是否被篡改了。

 

有很多种结合hash函数和密钥的MAC实现方法。我们假设H 是一个hash函数,‘+’ 代表连接运算. 下面的等式便代表一个能轻松实现MAC的方法:

MAC= H( key + message )

 

但是,上述方法存在一个严重的安全漏洞:利用大部分hash函数的内部实现机制,很容易在不知道密钥的情况下,通过附加数据到message, 便能产生一个有效的MAC

 

当然还有其他容易的替代方法,比如:MAC = H(message + key) 或者 H(key +message + key)。但是它们依旧存在安全隐患。

正是这些粗陋的MAC实现方法让大家意识到需要一种靠得住的MAC实现方法,这便是HMAC的由来。

 

HMAC(Hash-based Message Authentication Code)

下面的定义抄自[RFC2104]:

HMAC (k,m) = H ( (k XOR opad ) + H( (k XOR ipad ) + m ) )

其中

  • H 是一个Hash函数, 比如, MD5, SHA-1and SHA-256,

  • k 是一个密钥,从左到右用0填充到hash函数规定的block的长度,如果密钥长度大于block的长度,就对先对输入key作hash。

  • m 是需要认证的消息,

  • + 代表“连接”运算,

  • XOR 代表异或运算,

  • opad 是外部的填充常数(0x5c5c5c…5c5c, 一个block长度的十六进制常数constant),

  • ipad 是内部的填充常数 (0x363636…3636,一个block长度的十六进制常数constant)。

特定HMAC实现需要选择一个特定的hash函数。这些不同的HMAC实现通常标记为:HMAC-MD5,HMAC-SHA1, HMAC-SHA256等等. 

 

MAC用于消息认证

165313_7RfC_1469576.png

 

消息认证码

密码学中,通信实体双方使用的一种验证机制,保证消息数据完整性的一种工具。

安全性依赖于Hash函数,故也称带密钥的Hash函数。

消息认证码是基于密钥和消息摘要【hash】所获得的一个值,目的是用于验证消息的完整性,确认数据在传送和存储过程中未受到主动攻击

14165727_ohv6.png

 

Java提供的MAC算法实现

package encryption;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * MAC(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容
 * 了MD和SHA算法的特性,并在此基础上加入了密钥。因此,我们也常把MAC称为HMAC
 * (keyed-Hash Message Authentication Code)。
 * <p/>
 * Java 6实现
 * HmacMD5 128
 * HmacSHA1 160
 * HmacSHA256 256
 * HmacSHA384 384
 * HmacSHA512 512
 */
public class MACCoder {
    /**
     * 初始化HmacMD5密钥
     *
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacMD5Key() throws Exception {
        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
        // 产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacMD5消息摘要
     *
     * @param data 待做摘要处理的数据
     * @param key  密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacMD5(byte[] data, byte[] key)
            throws Exception {
        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        // 初始化Mac
        mac.init(secretKey);
        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * 初始化HmacSHA1密钥
     *
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacSHAKey() throws Exception {
        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1");
        // 产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacSHA1消息摘要
     *
     * @param data 待做摘要处理的数据
     * @param key  密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacSHA(byte[] data, byte[] key)
            throws Exception {
        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA1");
        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        // 初始化Mac
        mac.init(secretKey);
        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * 初始化HmacSHA256密钥
     *
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacSHA256Key() throws Exception {
        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
        // 产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacSHA256消息摘要
     *
     * @param data 待做摘要处理的数据
     * @param key  密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacSHA256(byte[] data, byte[] key) throws Exception {
        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA256");
        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        // 初始化Mac
        mac.init(secretKey);
        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * 初始化HmacSHA384密钥
     *
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacSHA384Key() throws Exception {
        // 初始化KeyGenerator
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA384");
        // 产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacSHA384消息摘要
     *
     * @param data 待做摘要处理的数据
     * @param key  密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacSHA384(byte[] data, byte[] key) throws Exception {
        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA384");
        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        // 初始化Mac
        mac.init(secretKey);
        // 执行消息摘要
        return mac.doFinal(data);
    }

    /**
     * 初始化HmacSHA512密钥
     *
     * @return byte[] 密钥
     * @throws Exception
     */
    public static byte[] initHmacSHA512Key() throws Exception {
        // 初始化
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA512");
        // 产生密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 获得密钥
        return secretKey.getEncoded();
    }

    /**
     * HmacSHA512消息摘要
     *
     * @param data 待做摘要处理的数据
     * @param key  密钥
     * @return byte[] 消息摘要
     * @throws Exception
     */
    public static byte[] encodeHmacSHA512(byte[] data, byte[] key) throws Exception {
        // 还原密钥
        SecretKey secretKey = new SecretKeySpec(key, "HmacSHA512");
        // 实例化Mac
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        // 初始化Mac
        mac.init(secretKey);
        // 执行消息摘要
        return mac.doFinal(data);
    }
}

=============END=============

转载于:https://my.oschina.net/xinxingegeya/blog/290594

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值