gpt4 book ai didi

encryption - 使用 ES256 的 JWT 签名无效

转载 作者:行者123 更新时间:2023-12-04 15:04:56 24 4
gpt4 key购买 nike

我正在尝试手动创建 ES256 JWT token 。我有一个用 python 编写的小脚本,它对使用 ecdsa-python 的 sha256 哈希进行签名。 .但签名在 jwt.io 上无效.
重现步骤:

  • 创建 base64 header + 有效负载:

  • eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0


  • 从 base64 header + 有效负载创建 SHA256 哈希:

  • FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F


  • 生成 ec_private key :

  • openssl ec -in ec_private.pem -noout -text


  • 使用python小程序对SHA256哈希进行ecdsa签名

  • from json import dumps
    from ellipticcurve.ecdsa import Ecdsa
    from ellipticcurve.privateKey import PrivateKey

    import base64

    def toBase64Url(input):
    return input.replace("+", "-").replace("/", "_").rstrip("=")

    # Generate privateKey from PEM string
    privateKey = PrivateKey.fromPem("""
    -----BEGIN EC PARAMETERS-----
    BgUrgQQACg==
    -----END EC PARAMETERS-----
    -----BEGIN EC PRIVATE KEY-----
    MHcCAQEEIJfChy9fKFItzqcb8DKBm+2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49
    AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBa
    Iv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==
    -----END EC PRIVATE KEY-----
    """)

    # Create message from json
    message = "FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F"

    signature = Ecdsa.sign(message, privateKey)

    # Generate Signature in base64. This result can be sent to Stark Bank in the request header as the Digital-Signature parameter.
    print("Base64: " + signature.toBase64())
    print("Base64Url: " +toBase64Url(signature.toBase64()))



    # To double check if the message matches the signature, do this:
    publicKey = privateKey.publicKey()

    print("Hash verification succesfull: " + str(Ecdsa.verify(message, signature, publicKey)))
    输出:

    Base64: MEQCIFyP4IoZGhzGfDCPX6fVxjtB+nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF+IHzxk8em+OMMHrJkPOhA==


    Base64Url: MEQCIFyP4IoZGhzGfDCPX6fVxjtB-nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF-IHzxk8em-OMMHrJkPOhA


    Hash verification succesfull: True


  • 检查签名jwt.io无效签名

  • eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.MEQCIFyP4IoZGhzGfDCPX6fVxjtB-nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF-IHzxk8em-OMMHrJkPOhA


    key :
    民众:

    -----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBaIv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==-----END PUBLIC KEY-----


    私有(private)的:

    -----BEGIN EC PRIVATE KEY-----MHcCAQEEIJfChy9fKFItzqcb8DKBm+2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBaIv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==-----END EC PRIVATE KEY-----


    我知道有很多 jwt 签名 python 库,但使用它是为了了解 jwt token 是如何创建的。
    编辑:
    正如@Topaco 指出的那样,该库使用曲线 secp256k1 而不是 secp256r1。 secp256r1 | prime256v1 | NIST P-256 都是不同标准组织为同一曲线选择的不同名称 ( Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS))。我把库改成了 python-ecdsa和代码:
    from ecdsa import SigningKey, NIST256p
    import base64

    def toBase64Url(input):
    return input.replace("+", "-").replace("/", "_").rstrip("=")


    sk = SigningKey.from_pem("""
    -----BEGIN EC PRIVATE KEY-----
    MHcCAQEEIJfChy9fKFItzqcb8DKBm+2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49
    AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBa
    Iv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==
    -----END EC PRIVATE KEY-----
    """)
    vk = VerifyingKey.from_pem("""
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0
    uoYcvX4Z7ROUIgYRvgfpsjBaIv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==
    -----END PUBLIC KEY-----
    """)
    signature = sk.sign(b"FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F")

    print(base64.b64encode(signature))
    print("Base64: " + base64.b64encode(signature).decode("utf-8"))
    print("Base64Url: " + toBase64Url(base64.b64encode(signature).decode("utf-8")))

    assert vk.verify(signature, b"FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F")
    print("Hash verification succesfull: " + str(vk.verify(signature, b"FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F")))
    输出:

    Base64: rMBgC0ismGdd5rd7n1L+LDsQ2UO5+cjBwPNYh+xBZvO6fKoJIfmfyNpxw+kxmyKWlK+55dF5eMH1u327DMJvvA==


    Base64Url: rMBgC0ismGdd5rd7n1L-LDsQ2UO5-cjBwPNYh-xBZvO6fKoJIfmfyNpxw-kxmyKWlK-55dF5eMH1u327DMJvvA


    Hash verification succesfull: True


    但是签名仍然无效。

    最佳答案

    您隐式使用散列的库,默认情况下应用 SHA1。 IE。为了与 ES256 兼容,必须明确指定 SHA256 并且必须使用未散列的 JWT,例如:

    from ecdsa import SigningKey, VerifyingKey
    import base64
    from hashlib import sha256

    def toBase64Url(input):
    return input.replace("+", "-").replace("/", "_").rstrip("=")

    jwt = b"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0"

    sk = SigningKey.from_pem("""
    -----BEGIN EC PRIVATE KEY-----
    MHcCAQEEIJfChy9fKFItzqcb8DKBm+2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49
    AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBa
    Iv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==
    -----END EC PRIVATE KEY-----
    """)
    vk = VerifyingKey.from_pem("""
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0
    uoYcvX4Z7ROUIgYRvgfpsjBaIv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==
    -----END PUBLIC KEY-----
    """)

    signature = sk.sign(jwt, hashfunc=sha256)

    print("Base64: " + base64.b64encode(signature).decode("utf-8"))
    print("Base64Url: " + toBase64Url(base64.b64encode(signature).decode("utf-8")))

    assert vk.verify(signature, jwt, hashfunc=sha256)
    print("Hash verification succesfull: " + str(vk.verify(signature, jwt, hashfunc=sha256)))
    一个可能的输出是:
    Base64: Mr4/DF87ek66E2GcAc+2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA==
    Base64Url: Mr4_DF87ek66E2GcAc-2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA
    Hash verification succesfull: True
    生成的签名 token
    eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.Mr4_DF87ek66E2GcAc-2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA
    然后可以在 https://jwt.io/ 上成功验证使用这里使用的公钥。

    关于encryption - 使用 ES256 的 JWT 签名无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66349140/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com