首页 > 后端开发 > Golang > 正文

Go语言中基于SHA224摘要生成ECDSA私钥并进行数字签名

霞舞
发布: 2025-11-22 17:21:01
原创
360人浏览过

Go语言中基于SHA224摘要生成ECDSA私钥并进行数字签名

本文详细阐述了在go语言中,如何根据用户id和密码短语的sha224摘要正确生成ecdsa私钥,并使用该私钥对消息进行数字签名。核心内容包括私钥d值的正确推导方法,即直接将哈希摘要转换为*big.int,以及ecdsa签名的标准流程,旨在帮助开发者避免常见的私钥生成错误,确保签名的安全性和正确性。

在Go语言中实现椭圆曲线数字签名算法(ECDSA)是常见的加密需求,尤其是在需要对特定消息进行身份验证或确保数据完整性时。一个典型的场景是根据用户ID和密码短语等特定输入,通过哈希算法派生出ECDSA私钥,进而使用该私钥对其他消息进行签名。本教程将详细介绍如何正确地在Go中使用crypto/ecdsa包,结合SHA224哈希算法,安全且准确地完成这一过程。

理解ECDSA私钥结构

ECDSA私钥的核心是一个大整数D。在Go语言的ecdsa.PrivateKey结构中,D字段的类型是*big.Int。这意味着任何用于生成私钥的原始数据(例如哈希摘要)最终都必须被正确地转换为一个*big.Int类型的值。

错误的私钥生成方法解析

一个常见的错误是将哈希函数的字节数组摘要先转换为一个固定大小的整数类型(如int64),然后再将其赋值给big.Int。例如,以下代码片段展示了这种不正确的做法:

// 错误示例:将SHA224摘要转换为int64,再赋值给big.Int
sha := sha256.New224()
// ... 写入数据 ...
sum := sha.Sum(nil) // []byte,SHA224摘要长度为28字节

var in int64
reader := bytes.NewReader(sum)
// 尝试将28字节的摘要读取到8字节的int64中
err := binary.Read(reader, binary.BigEndian, &in) 
if err != nil {
    // 可能会因为摘要长度超过int64而出现EOF错误,或者只读取了部分字节
    // 无论哪种情况,都会导致数据截断
}
prKey.D = big.NewInt(in) // 错误:数据丢失,安全性受损
登录后复制

SHA224哈希算法会产生一个28字节的摘要。将其直接读取到int64(8字节)中会导致严重的数据截断和信息丢失。这不仅使得生成的私钥无法正确反映原始哈希值,更在密码学上造成了不可接受的安全漏洞,因为私钥的熵和随机性被大大降低。

立即学习go语言免费学习笔记(深入)”;

ClipDrop
ClipDrop

Stability.AI出品的图片处理系列工具(背景移除、图片放大、打光)

ClipDrop 112
查看详情 ClipDrop

正确的私钥生成方法

正确的做法是将SHA224生成的28字节摘要直接转换为*big.Int。math/big包提供了SetBytes方法,能够将一个字节切片完整地解析为一个大整数。

以下是根据用户ID和密码短语(经过SHA224哈希)生成ECDSA私钥的正确实现:

package main

import (
    "bytes"
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "crypto/sha256"
    "encoding/binary"
    "fmt"
    "log"
    "math/big"
)

// NewKey 根据用户ID和密码短语的SHA224摘要生成ECDSA私钥
func NewKey(userId int64, pass string) (prKey ecdsa.PrivateKey) {
    // 1. 准备用于哈希的输入数据
    buf := new(bytes.Buffer)
    // 将userId以大端序写入缓冲区,确保字节序列化一致性
    err := binary.Write(buf, binary.BigEndian, userId)
    if err != nil {
        log.Fatalf("Failed to write userId: %v", err)
    }
    passArr := []byte(pass)

    // 2. 使用SHA224哈希算法计算摘要
    sha := sha256.New224()
    sha.Write(buf.Bytes())   // 写入userId的字节表示
    sha.Write(passArr)       // 写入密码短语的字节表示
    sum := sha.Sum(nil)      // 获取28字节的SHA224摘要

    // 3. 将SHA224摘要直接转换为*big.Int作为私钥D值
    // 这是关键步骤,确保不丢失任何信息
    prKey.D = new(big.Int).SetBytes(sum)

    // 4. 设置椭圆曲线。SHA224通常与P224曲线配合使用,因为它能提供足够的安全性。
    prKey.PublicKey.Curve = elliptic.P224()
    // 根据D值计算公钥X和Y坐标
    prKey.PublicKey.X, prKey.PublicKey.Y = prKey.PublicKey.Curve.ScalarBaseMult(prKey.D.Bytes())

    return prKey
}
登录后复制

代码解析:

  • 数据准备: userId是一个int64,需要通过binary.Write将其转换为字节序列,确保哈希输入的一致性。pass字符串直接转换为字节切片。
  • SHA224哈希: sha256.New224()创建一个SHA224哈希器。将userId和pass的字节序列写入哈希器,然后调用sha.Sum(nil)获取28字节的哈希摘要。
  • 私钥D值设置: 关键在于prKey.D = new(big.Int).SetBytes(sum)。这行代码将28字节的sum直接解析为一个大整数,并赋值给私钥的D字段,从而避免了数据截断问题。
  • 椭圆曲线设置: 选择了elliptic.P224()作为椭圆曲线。P224曲线的位数(224位)与SHA224摘要的位数(224位)相匹配,这是一种常见的匹配实践,可以确保密钥和哈希算法的安全强度一致。
  • 公钥计算: prKey.PublicKey.X, prKey.PublicKey.Y = prKey.PublicKey.Curve.ScalarBaseMult(prKey.D.Bytes()) 这行代码根据私钥D和选定的曲线自动计算出对应的公钥X和Y坐标,这是ECDSA规范的一部分。

消息哈希与数字签名

一旦私钥被正确生成,就可以用它来对消息进行签名。签名过程首先需要对消息内容进行哈希,然后使用ecdsa.Sign函数。

// 假设 enc 是一个将 big.Int 转换为字符串的辅助函数,例如 base64 编码
func enc(val string) string {
    // 实际应用中可能需要更复杂的编码,例如 base64 或 hex
    return fmt.Sprintf("encoded(%s)", val)
}

func main() {
    userId := int64(12345)
    pass := "mySecretPassphrase"
    srNonce := "server_nonce_xyz"
    clNonce := "client_nonce_abc"

    // 1. 生成私钥
    key := NewKey(userId, pass)
    fmt.Printf("Generated Private Key D: %s\n", key.D.String())

    // 2. 准备待签名的消息内容并进行SHA224哈希
    // 注意:这里需要确保消息内容的字节序列化方式与接收方一致
    msgBuffer := new(bytes.Buffer)
    binary.Write(msgBuffer, binary.BigEndian, userId) // userId作为int64写入
    msgBuffer.WriteString(srNonce)                    // server nonce作为字符串写入
    msgBuffer.WriteString(clNonce)                    // client nonce作为字符串写入

    // 对消息内容进行SHA224哈希
    msgHasher := sha256.New224()
    msgHasher.Write(msgBuffer.Bytes())
    msgHash := msgHasher.Sum(nil) // 获取消息的SHA224摘要

    // 3. 使用私钥对消息哈希进行签名
    // rand.Reader 提供密码学安全的随机数源
登录后复制

以上就是Go语言中基于SHA224摘要生成ECDSA私钥并进行数字签名的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号