一. 数字签名

设想一个场景:Alice 给 Bob 发送了一段消息(明天我请你吃饭),该消息使用 Bob 的公钥加密(公钥加密才能确保消息被截获后也只有 Bob 本人能用自己的私钥解密),但是由于 Bob 的公钥可能其他人也有,Tom 也可以使用 Bob 的公钥加密信息后发送给 Bob,所以 Bob 无法确保这条信息是 Alice 本人发送的,但是如果每条信息都加上 Alice 本人的签名,Bob 接收到信息之后就知道真的是 Alice 发送的,也能通过第三方机构防止 Alice 否认该消息。

数字签名就是由发送者对消息进行签名,具体方式是先对消息计算散列值,然后使用发送者的私钥对该散列值进行非对称加密得到数字签名,要发送的消息跟随数字签名一同发送。接收者拿到消息后,使用发送者的公钥对数字签名进行非对称解密得到散列值,然后对消息进行哈希计算得到散列值,将解密得到的散列值与哈希得到的散列值进行比较,如果二者相等,说明该消息确实是发送者本人发送的。

常用的进行数字签名的方式有 RSA 和椭圆曲线。

二. golang实战

1. 使用rsa进行数字签名与认证

crypto/rsa 包提供了 SignPKCS1v15 方法进行数字签名,VerifyPKCS1v15 方法进行数字签名认证。

使用 rsa 私钥文件进行数字签名步骤如下。

(1)读取私钥文件内容,使用 pem.Decode 将内容解析成 pem 格式块

(2)通过 x509.ParsePKCS1PrivateKey 将 pem 块中的 PKCS # 1, ASN.1 DER 格式的字符串解析成 rsa.PrivateKey

(3)计算发送内容散列值

(4)通过 rsa.SignPKCS1v15 使用私钥对散列值进行签名,该函数返回值就是数字签名内容

使用 rsa 公钥文件进行认证数字签名步骤如下。

(1)读取公钥文件内容,使用 pem.Decode 将内容解析成 pem 格式块

(2)通过 x509.ParsePKIXPublicKey 将 pem 块中的 DER 格式字符串解析成 rsa.PublicKey

(3)计算接收内容的散列值

(4)通过 rsa.VerifyPKCS1v15 使用公钥对散列值进行认证,如果该返回返回 err == nil,则表示认证成功

package mainimport ("crypto""crypto/ecdsa""crypto/rand""crypto/rsa""crypto/sha512""crypto/x509""encoding/pem""fmt""math/big""os"
)func rsaSignature(plainText []byte, privateKeyFile string) ([]byte, error) {// 读取私钥文件并解析成rsa.PrivateKeyfile, err := os.Open(privateKeyFile)if err != nil {return nil, err}stat, err := file.Stat()if err != nil {return nil, err}buf := make([]byte, stat.Size())file.Read(buf)defer file.Close()block, _ := pem.Decode(buf)privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)// 计算原始内容的散列值h := sha512.New()h.Write(plainText)hValue := h.Sum(nil)// 通过rsa.SignPKCS1v15使用私钥对原始内容散列值进行签名digestSign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA512, hValue)return digestSign, err
}func rsaVerifySign(plainText []byte, publicKeyFile string, signed []byte) bool {// 读取公钥文件并解析成rsa.PublicKeyfile, err := os.Open(publicKeyFile)if err != nil {return false}stat, err := file.Stat()if err != nil {return false}buf := make([]byte, stat.Size())file.Read(buf)defer file.Close()block, _ := pem.Decode(buf)publicKeyInt, err := x509.ParsePKIXPublicKey(block.Bytes)publicKey := publicKeyInt.(*rsa.PublicKey)// 计算原始内容的散列值h := sha512.New()h.Write(plainText)hValue := h.Sum(nil)// 确认签名err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA512,hValue, signed)return err == nil
}func main() {content := []byte("Hello digest sign")sign, err := rsaSignature(content, "private.pem")if err != nil {return}fmt.Println("signature:",sign)fmt.Println("verify result:", rsaVerifySign(content, "public.pem", sign))
}

运行结果如下所示。

2. 使用椭圆曲线进行数字签名与认证

package mainimport ("crypto""crypto/ecdsa""crypto/rand""crypto/rsa""crypto/sha512""crypto/x509""encoding/pem""fmt""math/big""os"
)func eccSignature(plainText []byte, privateKeyFile string) ([]byte, []byte, error){// 读取私钥文件并解析成ecdsa.PrivateKeyfile, err := os.Open(privateKeyFile)if err != nil {return nil, nil, err}stat, err := file.Stat()if err != nil {return nil, nil, err}buf := make([]byte, stat.Size())file.Read(buf)defer file.Close()block, _ := pem.Decode(buf)privateKey, _ := x509.ParseECPrivateKey(block.Bytes)// 计算原始内容的散列值h := sha512.New()h.Write(plainText)hValue := h.Sum(nil)r, s, err := ecdsa.Sign(rand.Reader, privateKey, hValue)rText, _ := r.MarshalText()sText, _ := s.MarshalText()return rText, sText, nil
}func eccVerifySign(plainText []byte, publicKeyFile string, rText []byte, sText []byte) bool {// 读取公钥文件并解析成ecdsa.PublicKeyfile, err := os.Open(publicKeyFile)if err != nil {return false}stat, err := file.Stat()if err != nil {return false}buf := make([]byte, stat.Size())file.Read(buf)defer file.Close()block, _ := pem.Decode(buf)publicKeyInt, err := x509.ParsePKIXPublicKey(block.Bytes)publicKey := publicKeyInt.(*ecdsa.PublicKey)// 计算原始内容的散列值h := sha512.New()h.Write(plainText)hValue := h.Sum(nil)var r, s big.Intr.UnmarshalText(rText)s.UnmarshalText(sText)return ecdsa.Verify(publicKey, hValue, &r, &s)
}func main() {r, s, err := eccSignature(content, "ecc_private.pem")if err != nil {return}fmt.Println("r:", string(r))fmt.Println("s:", string(s))fmt.Println("verify result:", eccVerifySign(content, "ecc_public.pem", r, s))
}

运行结果如下所示。

三. 数字签名存在的问题

验证签名的一端无法确认公钥是否真的属于发送者。如上,中间人 Tom 拦截了 Alice 的公钥,并使用自己的公钥发送给 Bob,之后 Tom 将 Alice 的数据拦截,再自己生成数据并进行签名,而 Bob 却无法得知公钥已经被偷换了。

这个问题使用数字证书可以解决。

golang实战-数字签名与认证相关推荐

  1. Golang中AK/SK认证的实现

    Golang实现AK/SK认证 一.AK/SK概述 1. 什么是AKSK 2. AK/SK认证过程 二.AK/SK认证例子 1. 设计ak/sk的请求参数 2. 数据库中保存sk 3. 客户端生成签名 ...

  2. Golang 实战——微信公众号课程提醒系统

    Golang 实战--微信公众号课程提醒系统 起因 最早开始学 Golang 已经是整整一年前了,当时就把基础语法那一块学完了,然后拿 Golang 写了点 leetcode 题.之后由于项目里一直用 ...

  3. Golang实战项目-B2C电商平台项目(8)

    Golang实战项目-B2C电商平台项目(8) 商品描述新增 商品描述表(tb_item_desc)和商品表(tb_item)具有主外键关系,商品的主键也是商品描述的主键,使用工具函数生成的主键也当作 ...

  4. 信息安全实践三之数字签名与认证实验【申请数字证书数字签名与认证】

    信息安全实践三之数字签名与认证实验[申请数字证书&数字签名与认证] 一.申请数字证书 二.数字签名与认证 1.加密文件&解密文件 2.文件签名&验证文件 3.文件签名加密&am ...

  5. 密码学---数字签名和认证协议---数字签名的基本概念

    数字签名的基本概念 数字签名应该满足的条件 数字签名的产生方式 由加密算法产生 单钥加密 公钥加密 实例 总结 由签名算法产生 数字签名的执行方式 直接方式 具有仲裁的方式 实例 数字签名应该满足的条 ...

  6. win11的数字签名驱动认证关闭

    Win11 取消数字签名 在我们使用win11开发的时候数字签名是一个很难受的东西,不关闭它我们就算安装的驱动,设备也不能正常连接,下面就针对win11的数字签名认证的关闭详细说说: 这里我使用的系统 ...

  7. golang中的消息认证

    消息认证码 go消息认证码的使用 有一个包: crypto/hmac > func New(h func() hash.Hash, key []byte) hash.Hash > - 返回 ...

  8. rabbitmq 客户端golang实战

    rabbitmq消息模式 rabbitmq中进行消息控制的组建可以分为以下几部分: exchange:rabbitmq中的路由部件,控制消息的转发路径: queue:rabbitmq的消息队列,可以有 ...

  9. 无限渗透实战(2)--绕过认证上校园网

    校园网大家都熟悉,一般都是开放的,然后连接之后有个登录页面,认证之后就可以上网了,那么我们怎么绕过认证直接上网 首先还是开始监听周围的ap,可以看到有许多的校园网 那么我们就需要开始监听周围的校园网, ...

最新文章

  1. C# 使用HttpWebRequest提交ASP.NET表单并保持Session和Cookie
  2. 你想过 Controller 这些方法里的参数是如何工作的吗?
  3. V2X 是自动驾驶重要基石,巨头纷纷抢滩布局
  4. Android开源框架——事件总线otto
  5. 11Linux服务器编程之:VFS虚拟文件系统,dup()函数和dup2()函数
  6. Linux 下 nginx反向代理与负载均衡
  7. 使用beego开发多表查询返回字段问题
  8. SpringCloud Sentinel 使用restTemplate的两种配置介绍
  9. Elasticsearch数据库下载
  10. 计算机显示不出来验证码,如何解决网页图片红叉显示不出来验证码图片没显示的电脑故障...
  11. linux内存的优化大师,Linux性能优化大师(调整操作系统参数)
  12. Zemax OpticsViewer
  13. 在Arduino上使用433MHz发送和接收模块
  14. 2020面试准备之MySQL索引
  15. dell计算机的硬盘如何分区,戴尔电脑分盘怎么分区
  16. word文档中如何添加目录
  17. 斑马打印机 android驱动,斑马ZC300驱动-斑马Zebra ZC300打印机驱动下载 v01.03.00官方版 - 51驱动网...
  18. 行业品牌监测报告|《中国汽车产业舆情报告2022(上半年)》
  19. 资本赋能|灵途科技获数千万元融资,深化人工智能物联网布局
  20. NFC模块化设计方案

热门文章

  1. 微服务架构之注册中心
  2. winscp普通用户上传文件没有权限解决
  3. OneForAll安装及使用
  4. 试用期的期限有多久,关于试用期你了解多少
  5. 计算机方向的综述投稿哪个期刊,COMPUTER
  6. kiss of death
  7. WARNING: Ignoring invalid distribution -ip解决问题
  8. adidas最软的鞋_哪种鞋子最舒服、最软?
  9. cass简码在内外业的应用与关联
  10. idea忽略某些文件,idea配 jdk、maven,改背景颜色,切换账号,彩虹进度条插件