热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

golang实现摘要签名和验证

golang实现摘要签名和验证的过程:两个步骤:下面是代码原文:

golang实现摘要签名和验证的过程:

两个步骤:

  1. 利用私钥对一个摘要进行签名。
$ ./test -command sign -key ./privatekey.pem -text "12345"
MEUCIE7DsGmTHJ3VGZec2UF9hRX7jq9Yd7F2kS7kEL132js8AiEA/ZlyIpo86Rn3waR8m2c4BtQPu8cNjYAnroibK+ujslY=
  1. 利用公钥验证签名是否有效。
$ ./test -command verify -cert ./publickey.pem -text "12345" -sign "MEQCIFuvcVHlztAN7YVehgCDYzVSo1Q10iTKeJE5ydxzfih5AiAC2ETt/8XuE1VHaGkLsiJkRSueh65Leq2VKkmFKxB/sQ=="
Successed to verify Signature and nonce

下面是代码原文:

package main

import (
    "fmt"
    "flag"
    "io/ioutil"
    "math/big"
    "crypto/ecdsa"
    "crypto/rand"
    "crypto/sha256"
    "crypto/x509"
    "encoding/asn1"
    "encoding/base64"
    "encoding/pem"
)

type ECDSASignature struct {
    R, S *big.Int
}

var (
    command     string
    certfile    string
    keyfile     string
    text        string
    sign        string
)

func main() {
    flag.StringVar(&command,    "command",  "",   "Command: sign/verify")
    flag.StringVar(&keyfile,    "key",      "",   "Private key file")
    flag.StringVar(&certfile,   "cert",     "",   "Public key file")
    flag.StringVar(&text,       "text",     "",   "Text content to be signed")
    flag.StringVar(&sign,       "sign",     "",   "Signed content to be verifed")
    flag.Parse()

    switch command {
    case "sign":
        if keyfile == "" || text == "" {
            fmt.Printf("ERROR: either key file or text is empty\n")
            return
        }
        Sign(keyfile, text)
    case "verify":
        if certfile == "" || text == "" || sign == "" {
            fmt.Printf("ERROR: either key file or text or sign is empty\n")
            return
        }
        Verify(certfile, text, sign)
    default:
        fmt.Printf("ERROR: unknown command\n")
        return
    }

}

func Sign(keyFile, text string) {
    keyBuff, err := ioutil.ReadFile(keyFile)
    if err != nil {
        fmt.Printf("ERROR: failed to read keystore file: %s, error: %v\n", keyFile, err)
        return
    }

    block, _ := pem.Decode(keyBuff)
    if block == nil {
        fmt.Printf("ERROR: block of decoded private key is nil\n")
        return
    }

    privKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    if err != nil {
        fmt.Printf("ERROR: failed get ECDSA private key, %v\n", err)
        return
    }
    ecPrivKey := privKey.(*ecdsa.PrivateKey)


    hash := sha256.Sum256([]byte(text))
    r, s, err := ecdsa.Sign(rand.Reader, ecPrivKey, hash[:])
    if err != nil {
        fmt.Printf("ERROR: failed to get signature, %v\n", err)
        return
    }

    // asn1 output DER format
    signature, err := asn1.Marshal(ECDSASignature{
        R: r,
        S: s,
    })
    if err != nil {
        fmt.Printf("ERROR: asn1.Marshal ECDSA signature: %v\n", err)
        return
    }

    fmt.Printf("%s\n", base64.StdEncoding.EncodeToString(signature))
}

func Verify(certFile, text string, sign string) {
    certBuff, err := ioutil.ReadFile(certFile)
    if err != nil {
        fmt.Printf("ERROR: failed to read keystore file: %s, error: %s\n", certFile, err)
        return
    }

    block, _ := pem.Decode(certBuff)
    if block == nil {
        fmt.Printf("ERROR: block of decoded private key is nil\n")
        return
    }

    cert, err := x509.ParseCertificate(block.Bytes)
    if err != nil {
        fmt.Printf("ERROR: failed get ECDSA private key, error: %v\n", err)
        return
    }

    arr := []byte(text)
    h := sha256.New()
    h.Write(arr)
    hashed := h.Sum(nil)

    signatureDec, _ := base64.StdEncoding.DecodeString(sign)
    sig := new(ECDSASignature)
    _, err = asn1.Unmarshal(signatureDec, sig)
    if err != nil {
        fmt.Printf("ERROR: failed unmashalling signature, error: %v", err)
        return
    }

    pub, _ := cert.PublicKey.(*ecdsa.PublicKey)
    if !ecdsa.Verify(pub, hashed[:], sig.R, sig.S) {
        fmt.Printf("ERROR: Failed to verify Signature: %v\n", err)
        return
    }
    fmt.Printf("Successed to verify Signature and nonce\n")
    return
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 我们


推荐阅读
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • 文章目录Golang定时器Timer和Tickertime.Timertime.NewTimer()实例time.AfterFunctime.Tickertime.NewTicke ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 进程(Process)是指计算机中程序对特定数据集的一次运行活动,是系统资源分配与调度的核心单元,构成了操作系统架构的基础。在早期以进程为中心的计算机体系结构中,进程被视为程序的执行实例,其状态和控制信息通过任务描述符(task_struct)进行管理和维护。本文将深入探讨进程的概念及其关键数据结构task_struct,解析其在操作系统中的作用和实现机制。 ... [详细]
  • 深入解析Spring框架中的双亲委派机制突破方法
    在探讨Spring框架中突破双亲委派机制的方法之前,首先需要了解类加载器的基本概念。类加载器负责将类的全限定名转换为对应的二进制字节流。每个类在被特定的类加载器加载后,其唯一性得到保证。然而,这种机制在某些场景下可能会限制灵活性,因此Spring框架提供了一些策略来突破这一限制,以实现更加动态和灵活的类加载。这些策略不仅能够提升系统的可扩展性,还能在复杂的运行环境中确保类的正确加载和管理。 ... [详细]
  • 本文介绍如何使用线段树解决洛谷 P1531 我讨厌它问题,重点在于单点更新和区间查询最大值。 ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 求助高手调试程序,非常感谢您的支持!在编写C语言程序时遇到了一些问题,具体代码如下:```c#include #include #include #define MAX 50int t;```希望有经验的开发者能提供指导,帮助解决调试中的难题。感谢您的时间和帮助! ... [详细]
author-avatar
黄霖hy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有