为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我用 openssl 和 golang 生成的 RSA 签名不同?

为什么我用 openssl 和 golang 生成的 RSA 签名不同?

Go
慕莱坞森 2022-01-10 16:23:08
我使用 openssl 命令对消息“Test.”进行签名,使用 hexdump 输出# echo "Test." | openssl rsautl -inkey privite.key -sign -hexdump0000 - 09 1b ce e2 4b 69 86 be-d7 b1 fb f0 ec e4 53 0e   ....Ki........S.0010 - ef 9c a4 7b db d3 21 d5-3e 78 23 61 89 34 7e bc   ...{..!.>x#a.4~.0020 - e9 1e 5a e9 f4 40 e6 53-07 e4 dd 1a fe 31 ec 42   ..Z..@.S.....1.B0030 - 98 a5 07 d4 7e d9 f4 01-2f ba a3 65 18 b7 69 a4   ....~.../..e..i. 十六进制字符串是 091bcee24b69...我的私人钥匙# cat private.Key-----BEGIN RSA PRIVATE KEY-----MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWuRTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7AIU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlStAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V-----END RSA PRIVATE KEY----------END RSA PRIVATE KEY-----`func GenerateSignature() {    block, _ := pem.Decode([]byte(prvKeyPem))    if block == nil {        panic("failed to parse root certificate PEM")    }    privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) //x509.ParseCertificate(block.Bytes)    if err != nil {        panic("failed to parse certificate: " + err.Error())    }    indata := "Test."    h := sha256.New()    h.Write([]byte(indata))    digest := h.Sum(nil)    s, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, digest)    if err != nil {        panic("failed to sign:" + err.Error())    }    fmt.Printf("%x\n", s)}func main() {    GenerateSignature()}运行此代码,以下是输出:52e1cce3810c1a89693cf6965d1035618820a9e3a7b95203d885c4153dc3f7424b98e3ba628a186f1074d672bb59a1c0788a9c2064951ca2326eb1bf8e3但我认为应该是:091bcee24b69...我哪里错了?谢谢
查看完整描述

3 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

除了helmbert 的回答中echo描述的添加的换行符之外,OpenSSL命令直接对提供的数据进行操作,而 Go 代码首先使用 SHA256 对数据进行哈希处理,然后对生成的摘要进行签名。rsautl


要使用 OpenSSL 执行与 Go 代码相同的操作,您可以使用带有选项的dgst命令-sign(请注意,我在这里也包含了该-n选项echo):


$ echo -n "Test." | openssl dgst -sha256 -sign private.key -hex

52e1cce3810c1a89693cf6965d1035618820a9e3a7b95203d885c4153dc3f7424b98e3ba628a186f1074d672bb59a1c0788a9c2064951ca2326eb1bf8e3e49e9

要在 Go 代码中不散列的情况下对原始消息进行签名,您可以将参数0的值传递hash给rsa.SignPKCS1v15:


indata := []byte("Test.")


s, err := rsa.SignPKCS1v15(nil, privKey, 0, indata)


查看完整回答
反对 回复 2022-01-10
?
慕沐林林

TA贡献2016条经验 获得超9个赞

该echo命令打印一个带有尾随换行符(\n或0a)的字符串:


> echo 'Test.' | hexdump -C

00000000  54 65 73 74 2e 0a                                 |Test..|

00000006

所以在你的情况下,你是Test.\n第一次签名,Test.第二次是在你的 Go 程序中。使用echo's-n开关来抑制尾随换行符:


> echo -n 'Test.' | hexdump -C

00000000  54 65 73 74 2e                                    |Test.|

00000005


查看完整回答
反对 回复 2022-01-10
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

这是一个非常有用的链接。


// Sign secret with rsa with PKCS 1.5 as the padding algorithm

// The result should be exactly same as "openssl rsautl -sign -inkey "YOUR_RSA_PRIVATE_KEY" -in "YOUR_PLAIN_TEXT""

signer, err := rsa.SignPKCS1v15(rand.Reader, rsaPrivateKey.(*rsa.PrivateKey), crypto.Hash(0), []byte(message))

https://github.com/bitmartexchange/bitmart-go-api/blob/master/bm_client.go


查看完整回答
反对 回复 2022-01-10
  • 3 回答
  • 0 关注
  • 215 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信