带有 PSS 填充的 RSA-SHA256 在 json 数据类型上出现无效签名错误,但适用于简单字符串(go lang againt python)

RSA-SHA256 with PSS padding invalid signature error on json data types but work on simple string (go lang againt python)

提问人:Luqman Jr 提问时间:11/16/2023 更新时间:11/16/2023 访问量:50

问:

我必须在 python 中从 json 数据对象分配签名,并在 go lang 中验证它,反之亦然

如果赋值和验证使用相同的语言或使用输入数据作为字符串,则它有效,但如果输入数据是字典,则失败

私钥

    -----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0DFzgagqwMPnPzeMpUldQRrdo2cmAzy/akPl05Rz0IzPms5Q
/dl4un1QMwQQRHKEDsJIrcCTOEsqtK/XG35Za9GsVxkoTuNPtDj8TpyvDHajPt3h
tqCIa2wRTsdvQIveVRixyCnsaR+crykpK8hOc7lG9Zh1l+9Y2Kb5shtWd/nXpUDW
2YXMnz2RWTmGhChsiW7VP52pH4tM870NTMKHW6tJJIdAYU47hToqe+uKaQ1x28GK
5+BbC9PWZwjKWyTJ5k5DmhR3LZc6jJOVMJvwdTOvqogwD7dcMgjx/VF8D4I6Z1F3
6UrB+JZC3oroU8E6ue29zJPSL0+5gVrkn+eN2wIDAQABAoIBAGEvhGz1FKgRiyRe
iQArZCXdJbN+licSt4Qil+mRthKXeN4aC4LEfvAHSWXXMsTQ9EZzeTvq1o6DwDbC
ktaZv6JuKVYrPz68K9vEcjs8NxbJVuEk8JWxEJ2cv+OXg56M7EerFGqM73gPMrQt
sbNneP/acH57IgG/0CiqoYr76fxsxBPftNlSv1PXWFyePjvdsi+EuRzzawoj/dGA
Zn2uBgewCDXVqwOVLIBCtvYLAHScK62a9pAk3bQ+wNoG+pYU3taiRzlKvO4ERXcp
L6HNggt3SL2JjuLJcg2DQnLnTkAgGHE73qlvpYnOmmrYdfpfoG9DX2tI7vraCdpY
HnuxquECgYEA7egFVcIYl7arTbr4Ddpu7KAIFxUn0q/nGSt0gbHQNHRJRIH8s75v
fYRU1UcjZZty+jnm/9I+lXB/M4CakIxWOOua2lyQeBeAxAvna9mjnpu3lssTdyCE
564C+jvVyjHMI1SXRu7ZDhH8Br1LUBn5+8zTgUal4b9YNON6NZqbHksCgYEA4Abs
Fip3jWcbAtelc9vfynW1ByMM3LDNXUzFXISs2xG1FDm5vuibWKF7oJhI/09IxvZK
AK+7aZm4WynpNEBDiKyRifZlnFJaFICRDztc79yAuQ/FFZ1Y/aQrlx8hdk7TdxWA
usmBhLGKTxAPzGr34b3q19fXE2ii67b5K2/FVLECgYEA4mcLrLEp9jdAjph/t69I
IKerC0x2uWns42cXWNV+7mw7zZZmhieUsj5c/RrV9Lwaj0bLLmlGZbDJXJnmfekP
pNuSYnv0gFTdlbQ+Z8SWkTpfXIGl5Jht4o0XCEwpCGKbgoPd8wMaTOmQjllWcsRF
wfsKzNwOwOb3al2Qz7JyLEECgYBDeXJEHthRS5u0GHVp1vCpjxhOJP1rvwirsELF
YeSaOtQaWmSann6jjEerEBL0atHVszqIyGUfIkCHnLDznuN4V9mh/weNtLQS9sI6
HzwXtodCtgA7SWATTQ4f/y1Z79X7SQuztpt+9uZcd876V8F/SW9hQU4zN1HSwxJ7
RbfekQKBgQC3AGvkPhPY953ILdRMFuKTx/rG24T42MNCWNGXvI1EQrPh1I9iP3xV
UalUNhbIxvzrIU6p/vhW8C2Hwh6viXyglkQ4VnpoYrgklRN/CKB+KFpMS52iUlrs
YLtKw3FU2q905gwRfMIcUyMnokU8C1VaSFslFw0o9AUbb5SDTTfJmg==
-----END RSA PRIVATE KEY-----

公钥

    -----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA0DFzgagqwMPnPzeMpUldQRrdo2cmAzy/akPl05Rz0IzPms5Q/dl4
un1QMwQQRHKEDsJIrcCTOEsqtK/XG35Za9GsVxkoTuNPtDj8TpyvDHajPt3htqCI
a2wRTsdvQIveVRixyCnsaR+crykpK8hOc7lG9Zh1l+9Y2Kb5shtWd/nXpUDW2YXM
nz2RWTmGhChsiW7VP52pH4tM870NTMKHW6tJJIdAYU47hToqe+uKaQ1x28GK5+Bb
C9PWZwjKWyTJ5k5DmhR3LZc6jJOVMJvwdTOvqogwD7dcMgjx/VF8D4I6Z1F36UrB
+JZC3oroU8E6ue29zJPSL0+5gVrkn+eN2wIDAQAB
-----END RSA PUBLIC KEY-----

Python 分配数据

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.backends import default_backend
import base64
import json
from cryptography.exceptions import InvalidSignature


user = {"name": "Foo", "age": 12, "email": "[email protected]"}

def sign_user(message) -> str:
    message_json = json.dumps(message)
    message_byts = message_json.encode("utf-8")
    key_file = open("private_key.pem", "rb")
    private_key = serialization.load_pem_private_key(
        key_file.read(), password=None, backend=default_backend()
    )
    signature = private_key.sign(
        message_byts,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256(),
    )

    signature_base64 = base64.b64encode(signature).decode("utf-8")
    print("\n\n", signature_base64, "\n\n")
    return signature_base64

从 python 创建的签名DReue2qd0Ir/TEQ5rDtegBSqgINIG+LqMnliwh3YbVUlb58TwfrcO1jWvR55LoBa524Fc2ZnWms3g7T2BFxlMxBAU8fFkZ33TYP7VTeImOiP2QThKeQZ11nzr8LjbPnimOj2+2YMXxrP0lTGvf69A5vpXhnPWa+jBXnyoHlw8cJL971FDfUwB7T3SQg+HIEmWk1xEjRedQzyLW+kAAICoeP8u9ClCJgdnd7a2IRDzJQ2A/OhrZaiwdSwrvCmiT9iezOT3t5yCiC/VkzL1BUQx3hl7AGSwzbKmoYqK+9USXkYNmjdOaUQMfql8p1cu46D3DF59dyRS6NWCZ54SkSyTg==

然后在Golang进行验证

验证功能

package certificate

import (
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "os"

    "github.com/goccy/go-json"
    "github.com/gofiber/fiber/v2/log"
)

func VerifySignature(encodedSignature string, message []byte) (bool, error) {
    // Decode signature
    decodedSignature, err := base64.StdEncoding.DecodeString(encodedSignature)
    if err != nil {
        log.Error(err)
        return false, err
    }
    // Load the public key from the file
    publicKeyFile, err := os.ReadFile(publicKeyName)
    if err != nil {
        log.Error(err)
        return false, err
    }

    publicKeyBlock, _ := pem.Decode(publicKeyFile)
    rsaKey, err := x509.ParsePKCS1PublicKey(publicKeyBlock.Bytes)
    if err != nil {
        log.Error(err)
        return false, err
    }

    // Hash the mesage usign SHA-256
    hash := sha256.New()
    hash.Write(message)
    hashedMessage := hash.Sum(nil)

    passOptions := rsa.PSSOptions{
        SaltLength: rsa.PSSSaltLengthAuto,
        Hash:       crypto.SHA256,
    }
    err = rsa.VerifyPSS(rsaKey, crypto.SHA256, hashedMessage[:], decodedSignature, &passOptions)
    if err != nil {
        return false, err
    }

    return true, nil
}

type User struct {
    Name string `json:"name"`
    Age uint `json:"age"`
    Email string `json:"email"`
}
var simpleUser = User{Name: "Foo", Age: 12, Email: "[email protected]"}




func verifySignatureUser(sign string, data User){
    dataBytes, err := json.Marshal(data)
    if err != nil {
        fmt.Print(err)
    }
    verified, err := VerifySignature(sign, dataBytes)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(verified)
}


func SimpleTest() {
    var signature = "DReue2qd0Ir/TEQ5rDtegBSqgINIG+LqMnliwh3YbVUlb58TwfrcO1jWvR55LoBa524Fc2ZnWms3g7T2BFxlMxBAU8fFkZ33TYP7VTeImOiP2QThKeQZ11nzr8LjbPnimOj2+2YMXxrP0lTGvf69A5vpXhnPWa+jBXnyoHlw8cJL971FDfUwB7T3SQg+HIEmWk1xEjRedQzyLW+kAAICoeP8u9ClCJgdnd7a2IRDzJQ2A/OhrZaiwdSwrvCmiT9iezOT3t5yCiC/VkzL1BUQx3hl7AGSwzbKmoYqK+9USXkYNmjdOaUQMfql8p1cu46D3DF59dyRS6NWCZ54SkSyTg=="
    verifySignatureUser(signature, simpleUser)
}

但是使用字符串数据类型,一切都很完美。

Python GO 加密 RSA

评论

1赞 Cerise Limón 11/16/2023
json.dumps(message)不产生与 相同的输出。在每个程序中打印 JSON 以观察差异。json.Marshal(data)
0赞 Luqman Jr 11/16/2023
在 go @CeriseLimón 中等价什么
4赞 Steffen Ullrich 11/16/2023
@LuqmanJr:请参阅 json 规范化。这有一个标准,并且有用于实现此标准的 Python 和 Go 的包。
0赞 Luqman Jr 11/17/2023
谢谢@SteffenUllrich我已经解决了 github.com/cyberphone/json-canonicalization

答: 暂无答案