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

为什么我用openssl和golang生成的RSA签名不同?,go,openssl,rsa,sign,Go,Openssl,Rsa,Sign,我使用openssl命令对消息“Test.”进行签名,并使用hexdump输出 # echo "Test." | openssl rsautl -inkey privite.key -sign -hexdump 0000 - 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

我使用openssl命令对消息“Test.”进行签名,并使用hexdump输出

# echo "Test." | openssl rsautl -inkey privite.key -sign -hexdump
0000 - 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.B
0030 - 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/KLADv7l3kK3ppMyCuLKoF0
fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
-----END RSA PRIVATE KEY-----
使用Golang生成签名

var prvKeyPem = `-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
-----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()
}
运行此代码,输出如下: 52E1E1CCE3810C1A89693CF6965D1035618820A9E3A7B95203D885C4153DC3F7424B98E3BA628A186F1074D672BB59A1C0788A9C2064951CA2326EB1BF8E3E49E9

但我认为应该是:

091bcee24b69


我的错在哪里?谢谢
echo
命令打印带有尾随换行符的字符串(
\n
0a
):

因此,在您的情况下,您将在Go程序中第一次签署
测试。\n
测试。
第二次签署。使用
echo
-n
开关抑制尾随换行符:

> echo -n 'Test.' | hexdump -C
00000000  54 65 73 74 2e                                    |Test.|
00000005

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

因此,在您的情况下,您将在Go程序中第一次签署
测试。\n
测试。
第二次签署。使用
echo
-n
开关抑制尾随换行符:

> echo -n 'Test.' | hexdump -C
00000000  54 65 73 74 2e                                    |Test.|
00000005

除了中所述的由echo添加的换行符之外,OpenSSL
rsautl
命令直接对提供的数据进行操作,而Go代码首先使用SHA256对数据进行散列,然后对结果摘要进行签名

要在OpenSSL中执行与Go代码相同的操作,您可以使用with the
-sign
选项(注意,我在这里也包括了
-n
选项以
echo
):

要以另一种方式对原始消息进行签名而不在go代码中进行散列,可以将
0
作为
hash
参数的值传递给:

indata:=[]字节(“测试”)
s、 err:=rsa.SignPKCS1v15(nil,privKey,0,indata)

除了中描述的由
echo
添加的换行符外,OpenSSL
rsautl
命令直接对提供的数据进行操作,而Go代码首先使用SHA256散列数据,然后对结果摘要进行签名

要在OpenSSL中执行与Go代码相同的操作,您可以使用with the
-sign
选项(注意,我在这里也包括了
-n
选项以
echo
):

要以另一种方式对原始消息进行签名而不在go代码中进行散列,可以将
0
作为
hash
参数的值传递给:

indata:=[]字节(“测试”)
s、 err:=rsa.SignPKCS1v15(nil,privKey,0,indata)

这是一个非常有用的链接

// 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))

这是一个非常有用的链接

// 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))

请注意,并非所有
echo
实现都支持
-n
开关。请注意,并非所有
echo
实现都支持
-n
开关。在您的帮助下,我的问题已经解决,非常感谢。另一个问题,我得到字符串“Test.\n”使用以下命令:
$openssl rsautl-verify-inkey pub.key-pubin-in签名
$Test.
Bug在Golang中,我只找到了一个函数VerifyPKCS1v15来验证签名,但在调用该函数之前,我必须知道这个字符串“Test.\n”,以便生成参数**hashed88
func VerifyPKCS1v15(pub*PublicKey,hash crypto.hash,hash[]byte,sig[]byte)
我可以像openssl命令一样从公钥和签名器中获取字符串“Test.\n”吗?在您的帮助下,我的问题已经解决,非常感谢您。还有一个问题,我得到了字符串“Test.\n”使用以下命令:
$openssl rsautl-verify-inkey pub.key-pubin-in签名
$Test.
Bug在Golang中,我只找到了一个函数VerifyPKCS1v15来验证签名,但在调用该函数之前,我必须知道这个字符串“Test.\n”,以便生成参数**hashed88
func VerifyPKCS1v15(pub*PublicKey,hash crypto.hash,hash[]byte,sig[]byte)
我可以像openssl命令一样从公钥和signatrue中获取字符串“Test.\n”吗?