六、消息认证码

  • 消息认证码 — 消息被正确传送了吗?
  • 消息的完整性(integrity), 指的是“消息没有被篡改"这一性质,完整性也叫一致性
  • 消息的认证(authentication)指的是“消息来自正确的发送者"这一性质
  • 消息认证码(message authentication code)是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为MAC。
  • 消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为MAC值
  • 根据任意长度的消息输出固定长度的数据,这一点和单向散列函数很类似。但是单向散列函数中计算散列值时不需要密钥,而消息认证码中则需要使用发送者与接收者之间共享的密钥。
  • 要计算MAC必须持有共享密钥,没有共享密钥的人就无法计算MAC值,消息认证码正是利用这一性质来完成认证的。此外,和单向散列函数的散列值一样,哪怕消息中发生1比特的变化,MAC值也会产生变化。
  • 消息认证码有很多种实现方法,大家可以暂且这样理解:消息认证码是一种与密钥相关联的单向散列函数

1.消息认证码的使用步骤

    1. 发送者Alice与接收者Bob事先共享密钥。
    1. 发送者Alice根据汇款请求消息计算MAC值(使用共享密钥)。
    1. 发送者Alice将汇款请求消息和MAC值两者发送给接收者Bob。
    1. 接收者Bob根据接收到的汇款请求消息计算MAC值(使用共享密钥)。
    1. 接收者Bob将自己计算的MAC值与从Alice处收到的MAC值进行对比。
    1. 如果两个MAC值一致,则接收者Bob就可以断定汇款请求的确来自Alice(认证成功);如果不一致,则可以断定消息不是来自Alice(认证失败)。

2.HMAC

  • HMAC是一种使用单向散列函数来构造消息认证码的方法(RFC2104),其中HMAC的H就是Hash的意思。
  • HMAC中所使用的单向散列函数并不仅限于一种,任何高强度的单向散列函数都可以被用于HMAC,如果将来设计出新的单向散列函数,也同样可以使用。
  • 使用SHA-I、MD5、RIPEMD-160所构造的HMAC,分别称为HMAC-SHA-1、HMAC-MD5和HMAC-RlPEMD。
  • 最后得到的MAC值,一定是一个和输入的消息以及密钥都相关的长度固定的比特序列。
2.1 Go中对HMAC的使用
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"encoding/base64"
)

// 生成消息认证码
func GenerateHMAC(src, key []byte) []byte {
	// 1. 创建一个底层采用sha256算法的 hash.Hash 接口
	myHmac := hmac.New(sha256.New, key)
	// 2. 添加测试数据
	myHmac.Write(src)
	// 3. 计算结果
	result := myHmac.Sum(nil)

	return result
}

//验证消息认证码
func VerifyHMAC(res, src, key []byte) bool {
	// 1. 创建一个底层采用sha256算法的 hash.Hash 接口
	myHmac := hmac.New(sha256.New, key)
	// 2. 添加测试数据
	myHmac.Write(src)
	// 3. 计算结果
	result := myHmac.Sum(nil)
	// 4. 比较结果
	return hmac.Equal(res, result)
}

func main() {
	key := []byte("我是消息认证码秘钥")
	src := []byte("我是消息认证码测试数据")
	result := GenerateHMAC(src, key)
	fmt.Println("result bytes=", result)
	fmt.Println("result base64=", base64.StdEncoding.EncodeToString(result))
	final := VerifyHMAC(result, src, key)
	if final {
		fmt.Println("消息认证码认证成功!!!")
	} else {
		fmt.Println("消息认证码认证失败 ......")
	}
}
  • 结果输出
result bytes= [45 172 206 186 170 21 159 60 142 5 231 19 247 120 175 198 229 119 255 233 72 24 157 223 5 10 211 179 143 80 96 70]
result base64= LazOuqoVnzyOBecT93ivxuV3/+lIGJ3fBQrTs49QYEY=
消息认证码认证成功!!!

3.消息认证码的密钥配送问题

  • 在消息认证码中,需要发送者和接收者之间共享密钥,而这个密钥不能被主动攻击者Mallory获取。如果这个密钥落入Mallory手中,则Mallory也可以计算出MAC值,从而就能够自由地进行篡改和伪装攻击,这样一来消息认证码就无法发挥作用了。
  • 发送者和接收者需要共享密钥,这一点和我们介绍的对称加密很相似。实际上,对称加密的密钥配送问题在消息认证码中也同样会发生。关于秘钥的配送,使用非对称加密的方式可以解决。

4.消息认证码无法解决的问题

4.1 对第三方证明
  • 假设Bob在接收了来自Alice的消息之后,想要向第三方验证者Victor证明这条消息的确是Alice发送的,但是用消息认证码无法进行这样的证明,这是为什么呢?
  • 首先,Victor要校验MAC值,就需要知道Alice和Bob之间共享的密钥。
  • 假设Bob相信Victor, 同意将密钥告诉Victor,即便如此,Victor也无法判断这条消息是由Alice发送的,因为Victor可以认为:“即使MAC值是正确的,发送这条消息的人也不一定是Alice,还有可能是Bob。"
  • 能够计算出正确MAC值的人只有Alice和Bob,在他们两个人之间进行通信时,可以断定是对方计算了MAC值,这是因为共享这个密钥的双方之中,有一方就是自己。然而,对于第三方Victor、Alice或Bob却无法证明是对方计算了MAC值,而不是自己。
  • 数字签名就可以实现对第三方的证明
4.2 防止否认
  • 假设Bob收到了包含MAC值的消息,这个MAC值是用Alice和Bob共享的密钥计算出来的,因此Bob能够判断这条消息的确来自Alice。
  • 但是,上面我们讲过,Bob无法向验证者Victor证明这一点,也就是说,发送者Alice可以向Victor声称:“我没有向Bob发送过这条消息。”这样的行为就称为否认(repudiation)。
  • Alice可以说“这条消息是Bob自己编的吧",“说不定Bob的密钥被主动攻击者Mallory给盗取了,我的密钥可是妥善保管着呢" 等。说白了,就是Alice和Bob吵起来了。
  • 即便Bob拿MAC值来举证,Victor也无法判断Alice和Bob谁的主张才是正确的,也就是说,用消息认证码无法防止否认(nonrepudiatlon)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值