golang中的消息认证

消息认证码

go消息认证码的使用

有一个包: crypto/hmac

> func New(h func() hash.Hash, key []byte) hash.Hash
> - 返回值: hash接口
> - 参数1: 函数函数的函数名
> 	sha1.new
> 	md5.new
> 	sha256.new
> - 参数2: 秘钥
> 
> 第二步: 添加数据
> type Hash interface {
>     // 通过嵌入的匿名io.Writer接口的Write方法向hash中添加更多数据,永远不返回错误
>     io.Writer
>     // 返回添加b到当前的hash值后的新切片,不会改变底层的hash状态
>     Sum(b []byte) []byte
>     // 重设hash为无数据输入的状态
>     Reset()
>     // 返回Sum会返回的切片的长度
>     Size() int
>     // 返回hash底层的块大小;Write方法可以接受任何大小的数据,
>     // 但提供的数据是块大小的倍数时效率更高
>     BlockSize() int
> }
> type Writer interface {
>     Write(p []byte) (n int, err error)
> }
> 第三步: 计算散列值

使用步骤

  1. 前提条件:
    • 在消息认证码生成的一方和校验的一方, 必须有一个秘钥
    • 双方约定好使用同样的哈希函数对数据进行运算
  2. 流程:
    • 发送者:
      • 发送原始法消息
      • 将原始消息生成消息认证码
        • ((原始消息) + 秘钥) * 函数函数 = 散列值(消息认证码)
      • 将消息认证码发送给对方
    • 接收者:
      • 接收原始数据
      • 接收消息认证码
      • 校验:
        • ( 接收的消息 + 秘钥 ) * 哈希函数 = 新的散列值
        • 通过新的散列值和接收的散列值进行比较
// 生成消息认证码
func GenerateHamc(plainText, key []byte)[]byte {
   // 1.创建哈希接口, 需要指定使用的哈希算法, 和秘钥
   myhash := hmac.New(sha1.New, key)
   // 2. 给哈希对象添加数据
   myhash.Write(plainText)
   // 3. 计算散列值
   hashText := myhash.Sum(nil)
   return hashText
}

// 验证消息认证码
func VerifyHamc(plainText, key, hashText []byte) bool {
   // 1.创建哈希接口, 需要指定使用的哈希算法, 和秘钥
   myhash := hmac.New(sha1.New, key)
   // 2. 给哈希对象添加数据
   myhash.Write(plainText)
   // 3. 计算散列值
   hamc1 := myhash.Sum(nil)
   // 4. 两个散列值比较
   return hmac.Equal(hashText, hamc1)
}

func main () {
   src := []byte("在消息认证码中,需要发送者和接收者之间共享密钥,而这个密钥不能被主动攻击者Mallory获取。" +
      "如果这个密钥落入Mallory手中,则Mallory也可以计算出MAC值,从而就能够自由地进行篡改和伪装攻击," +
      "这样一来消息认证码就无法发挥作用了。")
   key := []byte("helloworld")
   hamc1 := GenerateHamc(src, key)
   bl := VerifyHamc(src, key, hamc1)
   //fmt.Printf("校验结果: %t\n", bl)
   fmt.Println(bl)
}

消息认证码的问题

  1. 弊端
    • 有秘钥分发困难的问题
  2. 无法解决的问题
    • 不能进行第三方证明
    • 不能防止否认

猜你喜欢

转载自blog.csdn.net/ma2595162349/article/details/113004008