【问题标题】:Golang signing a struct using rsaGolang 使用 rsa 对结构进行签名
【发布时间】:2018-07-21 16:06:02
【问题描述】:

我有一个结构体Transaction,其中包含以下字段,

type Transaction struct {
    Sender    string `json:"sender"`
    Receiver  string `json:"receiver"`
    Signature string `json:"signature"`
    Amount    int64  `json:"amount"`
}

我还有一个函数GetPrivateKey(),它返回一个*rsa.PrivateKey

func GetPrivateKey() (*rsa.PrivateKey, error) {
    key, err := ioutil.ReadFile("/Users/xxx/.ssh/id_rsa")
    if err != nil {
        return nil, err
    }

    block, _ := pem.Decode(key)
    der, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
       return nil, err
    }
    return der, err
 }

我的计划是使用系统中已有的私钥对结构transaction的内容进行签名,然后将其作为字符串存储在结构中的字段signature中,为此,我有一个函数@ 987654328@

func SignPayload(txnObj *Transaction) error {
    privateKey, err := GetPrivateKey()
    if err != nil {
        panic(err)
    }
    bodyHash, err := rsa.SignPKCS1v15(rand.Reader, privateKey, 
                     crypto.SHA256, []byte(fmt.Sprintf("%v", *txnObj)))
    if err != nil {
        panic(err)
    }
    txnObj.Signature = string(bodyHash)
    log.Println(txnObj.Signature)
    return err
}

不幸的是,这不起作用,rsa.SignPKCS1v15() 抛出一个错误说:

crypto/rsa:输入必须是散列消息

这里的最终目标是使用此签名通过将其与字段sender 中存在的公钥进行比较来验证结构的真实性。 我是密码学的绝对新手,我在这里做错了什么?更重要的是,我该怎么做?

提前致谢!

【问题讨论】:

    标签: go cryptography rsa


    【解决方案1】:

    这里有两件事:

    • 只能对小消息进行签名,这就是它通常是散列的原因。 rsa.SignPKCS1v15 期望消息长度与哈希算法的输出匹配(256 位,对于 sha-256 或 32 字节)
    • 不要使用结构的%v 表示,而是将其序列化

    第一个是spelled out in the rsa docs。给定一条消息,您可以使用以下方式对其进行签名:

    message := []byte("message to be signed")
    hashed := sha256.Sum256(message)
    
    signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
    if err != nil {
        panic(err)}
    }
    

    第二点更多是关于使您的代码更健壮。您不希望更改 %v 逻辑或添加未导出的字段来导致问题。您可能还想检查 Go 以外语言的签名。

    因此,您应该首先编组您的结构。你已经有了 json 标签,所以很简单:

    message, err := json.Marshal(txnObj)
    if err != nil {
        panic(err)
    }
    

    Message 是上面传递给sha256.Sum256 的字节片。

    验证签名时,您需要确保将结构的 Signature 字段清零,对其进行编组、散列并调用 rsa.VerifyPKCS1v15

    【讨论】:

    • 感谢您的澄清,很好的回答。
    猜你喜欢
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2023-04-02
    • 2013-05-01
    • 1970-01-01
    • 2013-11-25
    相关资源
    最近更新 更多