为什么golang的RSA签名结果和OpenSSL命令的不一样?

Why is the RSA signature result of golang different from that of OpenSSL command?

最近在项目中遇到RSA签名。希望有经验的兄弟帮忙

我使用的OpenSSL(版本1.0.2u)命令:

echo -n -e "test\n"|openssl dgst -sha256 -sign ./apiclient_key.pem| openssl base64 -A

结果如下

pyoBMuN8UqRGLVR7YcQ11yn+dQ9rSU/fB7obQhs27eotvd51q+E8BqxB6AYQDTnlqAQnOiR1rnuxPjlGkAOaPxpCqfhS5VGblh3HuNNHiycdKKa5mM1XyaWROiL7YpyYHRUcblkICW4XEN8v5wyFHxQ+TZfBN8fdqmlLdSczZ66YnIUgaWjBkdC1UH9GqMOQkySaQbgxjh4WhWvVE4umlKz+lAj9OLBhqI/ZXcs6gPFIpyNl8hlMPi6QOxFDSPZmQZl9G7mzx4E0lBoCY5XJtm5VwG3IYTryKZvSF0/GjVyR6QA3/sY25WCPL6f/y0biovk+mJ2KvPvPX26hK4DYug==

我的签名相关golang代码:

// get private key
bPrivateKey, err := ioutil.ReadFile("./apiclient_key.pem")
if err != nil || bPrivateKey == nil {
    log.Println(err)
    return
}
block, _ := pem.Decode(bPrivateKey)
if block == nil {
    return
}
pKeyInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
    log.Println(err)
    return
}
pKey, ok := pKeyInterface.(*rsa.PrivateKey)
if !ok {
    return
}
// sign
strForSign = "test\n"
shaForSign := sha256.New()
shaForSign.Write([]byte(strForSign))
hashedForSign := shaForSign.Sum(nil)
rawSignature, err := rsa.SignPKCS1v15(rand.Reader, pKey, crypto.SHA256, hashedForSign)
if err != nil {
    log.Println(err)
    return
}
signature := base64.StdEncoding.EncodeToString(rawSignature)
log.Println(signature)

结果如下

NcW5pBmUfHqVNus1PTDjGOilazWkcyxquGc/Ldu5IAjg/gAIQOKBGp7rs8thec/THhWKjZOJtZ1Xvv85vc+bG5bB4IuCZp+wkUMgDC3kFuTPjtLEBBnlhshZ1nS0Haq5BuS6aWAF9sIz6Ulq9dLMjaOAACijwEltdOdkRo8Z5V01CZMOPM3FI0dVvTGOvXxsMvLjw3XPAxNpajXhxTTGZB5jElDkTb61U/cZ9tM+iVpd7Oo+vxvgCsrx2VhV4gURrxndj3V6Nc2iNV2bByrgw8XK1htzkqLqZpWo8JF8i5LdMrfaMukn6aikhWKFOo2icatjowiSQAAXrj9EnnrbQA==

apicclient_key.pem文档内容如下:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+YVIbsE+b5Rsg
oSrcV7H21SBICjTcCKDiqEv94ghL3MfBjW5g/m9o9dcTdBpBED4NaWX+N9+aXi9o
aGNUU5Eghg1eZeFcw0utasuQnMwIc64K4L60FQxFVHjEoV0uEML7TkxMIPWh2Vdm
qyOAmBZldPBMRTXyQoqohlS0Z8z1NAwz9mVy9rnNaIgQT5FFjvfPW2dvCuvLjgo8
wqWfgJttB/8ptcUZoJU7EtPqLheEibuSDQtjGBVxttq9O6Eo3zyS2I6/0JZCRGqF
RRIqPmD2ivpI7ZwXE/cEk9R6Dv9lGZS4XZxUFpDhJnQircnH3N41nYgnFaWDm7sJ
BP9TZnkBAgMBAAECggEATumOHDYHuYnMpcjIOE8NUE/lMpcwc+gLsAesgA7Z+4AH
OL5D+2ZbjbkhLkoYu9Fctzhx8177i0PxCKkESybcaAvIrNE0CbxVuQskV8v2cqZo
hM/FnGWBEZfC+1YbhoWiHILG82NSDYVGSiMz8xCXb/R5ylOB2eolCVes8p54AUab
KU58GGFEYFMGnccy9SZ7QkG00fBLU7vJ9MINzpujujDTOS+f+MTkPpushjfUqWyj
2pfj235xajVTeHPag4Gig5wwmblu+fUxEsXtIkvM91/5GzsRVh6VIqSABhrsUXr4
zhFuiqw/ZhtYa32HnU6cpMOKIbDaHu31C0bE/CEcwQKBgQDtnEnEd8+QAuLfSsV6
wGBXV5cfnmmlkWKFxhDzW0solk9eBDKfIVw7Zw1NdanBlIrK187sOETArzeVEVFK
J4r4CnPuguTMoik5AXNAOxnA5OrYP4Tn8xk3AV9Kuh16f+CAt6zzVQQo2FXzoteK
NOlLM+oLe+XrY8kQFJkv4GXDmQKBgQDNHUVPmP2FeHbpU79mwun143HGDSPDslek
nOEv+/1Cm9+L1sla1Yglb6OZrk9wxjnw0c4HnQV5+l1K6c72ujI840BobjUqMqCW
mvb14lr/p1pVyAsSbMBlGR6EgR/QkMD/CL7KTKa/RwiM393oslvxvdGxCPuKEISN
rCt/zxLBqQKBgEHXPNmkGW/eXN9i6LXK+Oc67jVkwAGQ96v55liIw5rLi9KRdzWB
GP2c4KLGJ/PsJUlv43axYNvDsbMsyUmzC18QBm/g9WV+yc1yCW2S8t/wjuK9NybO
xf3n82/RgrmfFaaVPudud2iaCbcpOHCjmMGt8PydqGhBjkVWb9xEYe6BAoGBAIjx
/hDC6KFwaJQoIiaOBH7zOEcvBq3mKLXzODY9XD5Yq8xFv3IyFxBHlUdKJif5cT3k
Flbm830ZN6iIqnH4pwoYACy5SC3AV4+2LyTD2FXQenPDeAD5MwtM1h9JxuANhY3B
XQDcZIhY+NB1t0dhrhmczqAQi0EG/jlItlJDAxbhAoGAV5l05wHqqwEZroN0gXq2
86JTftIRzmstgs6O/yfjuInqHjMGp1fTOLyqbwA6+ZrHmzNyyoD8jiGW068LC1ue
7xucV/dYuUXUXOcX0HN/trIdMkl5jQWkrXSKP5o5ekw9gsMcicWFUBXdnJMxCcYb
i8CRH78crAdaIqZ+2buIozo=
-----END PRIVATE KEY-----
$ echo -n -e "test\n" | openssl dgst -sha256 -sign ./apiclient_key.pem | openssl base64 -A
NcW5pBmUfHqVNus1PTDjGOilazWkcyxquGc/Ldu5IAjg/gAIQOKBGp7rs8thec/THhWKjZOJtZ1Xvv85vc+bG5bB4IuCZp+wkUMgDC3kFuTPjtLEBBnlhshZ1nS0Haq5BuS6aWAF9sIz6Ulq9dLMjaOAACijwEltdOdkRo8Z5V01CZMOPM3FI0dVvTGOvXxsMvLjw3XPAxNpajXhxTTGZB5jElDkTb61U/cZ9tM+iVpd7Oo+vxvgCsrx2VhV4gURrxndj3V6Nc2iNV2bByrgw8XK1htzkqLqZpWo8JF8i5LdMrfaMukn6aikhWKFOo2icatjowiSQAAXrj9EnnrbQA==%  

我会仔细检查一下 运行 shell 中的 openssl 命令。 stdout 的任何无关输出都会更改签名。

我从 1.0.2n-fips 和 openssl-3.0.0-alpha6 以及 运行 你本地的 Go 代码得到了“NcW..”签名。