Golang中Crypto/rsa问题 - 如何直接签名数据而不使用哈希的API

Golang中Crypto/rsa问题 - 如何直接签名数据而不使用哈希的API 我有一些数据需要在通过网络传输前进行签名。我尝试使用 crypto/rsa 包中的 SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) 来对数据进行签名,但该 API 要求数据在签名前必须先进行哈希处理。这带来了一个问题,因为接收端验证的是数据的签名,而不是哈希值。是否有其他可用的 API 可以让我直接对数据进行签名而无需哈希处理?

func main() {
    fmt.Println("hello world")
}

更多关于Golang中Crypto/rsa问题 - 如何直接签名数据而不使用哈希的API的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中Crypto/rsa问题 - 如何直接签名数据而不使用哈希的API的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言的crypto/rsa包中,确实没有直接提供对原始数据进行RSA签名而不先进行哈希处理的API。这是因为RSA签名通常需要先对数据进行哈希处理,这是出于安全性和性能的考虑。

不过,你可以通过使用crypto/rsa包中的底层函数来实现直接签名。具体来说,可以使用rsa.SignPKCS1v15函数,但需要手动处理哈希步骤,或者使用rsa.SignPSS函数(如果适用)。但请注意,直接对原始数据签名可能存在安全风险,通常不推荐。

以下是一个示例,展示如何直接对数据进行签名而不使用哈希API,通过手动处理哈希步骤:

package main

import (
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "fmt"
    "log"
)

func main() {
    // 生成RSA密钥对(仅示例,实际应用中应使用持久化密钥)
    privKey, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
        log.Fatal("密钥生成失败:", err)
    }

    // 原始数据
    data := []byte("需要签名的数据")

    // 手动计算哈希(例如SHA-256)
    hash := sha256.Sum256(data)

    // 使用SignPKCS1v15进行签名,传入哈希值
    signature, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hash[:])
    if err != nil {
        log.Fatal("签名失败:", err)
    }

    fmt.Printf("签名结果: %x\n", signature)

    // 验证签名(示例)
    err = rsa.VerifyPKCS1v15(&privKey.PublicKey, crypto.SHA256, hash[:], signature)
    if err != nil {
        log.Fatal("验证失败:", err)
    } else {
        fmt.Println("签名验证成功")
    }
}

在这个示例中:

  • 我们首先生成了一个RSA密钥对。
  • 然后对原始数据data手动计算SHA-256哈希。
  • 使用rsa.SignPKCS1v15函数对哈希值进行签名。
  • 最后使用rsa.VerifyPKCS1v15验证签名。

注意:直接对原始数据签名(不进行哈希)通常不安全,因为RSA算法对输入数据大小有限制(例如,对于2048位密钥,输入数据不能超过245字节)。哈希处理可以确保数据大小适合签名,并提高安全性。如果必须直接签名,可以考虑使用rsa.EncryptPKCS1v15,但这实际上不是标准签名方法:

// 不推荐:直接使用加密函数模拟签名(仅用于演示)
encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, &privKey.PublicKey, data)
if err != nil {
    log.Fatal("加密失败:", err)
}
// 这实际上不是标准签名,接收方需要使用私钥解密来“验证”

总之,标准做法是使用哈希处理。如果接收方需要验证原始数据,应确保他们也能访问原始数据并重新计算哈希进行验证。

回到顶部