首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ES256的无效JWT签名

使用ES256的无效JWT签名
EN

Stack Overflow用户
提问于 2021-02-24 10:37:20
回答 1查看 3K关注 0票数 3

我正在尝试手动创建一个ES256 JWT令牌。我有一个用python编写的小脚本,它签署了一个使用sha256的长尾蟒哈希。但是该签名在jwt.io上无效。

复制步骤:

  1. 创建base64头+有效载荷:

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0

  1. 从SHA256头+有效载荷创建base64哈希:

FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F

  1. 生成ec_private密钥:

openssl ec -in ec_private.pem -noout -text

  1. 使用小型python程序对SHA256哈希签名
代码语言:javascript
复制
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)))

输出:

MEQCIFyP4IoZGhzGfDCPX6fVxjtB+nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF+IHzxk8em+OMMHrJkPOhA==:MEQCIFyP4IoZGhzGfDCPX6fVxjtB-nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF-IHzxk8em-OMMHrJkPOhA Base64Url: MEQCIFyP4IoZGhzGfDCPX6fVxjtB-nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF-IHzxk8em-OMMHrJkPOhA Hash验证成功: True

  1. 检查jwt.io中的签名给无效签名

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.MEQCIFyP4IoZGhzGfDCPX6fVxjtB-nrXDVhOTQwdc5vu8z4eAiBNalfGHqdaO3nCmTqimpAHF-IHzxk8em-OMMHrJkPOhA

键:

公众:

--开始使用公钥- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0 uoYcvX4Z7ROUIgYRvgfpsjBaIv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ== -末端公钥

私人:

--开始EC私钥- MHcCAQEEIJfChy9fKFItzqcb8DKBm+2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49 AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBa Iv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ==

我知道有很多jwt对python库进行签名,但是使用它来了解如何创建jwt令牌。

编辑:

正如@Topaco所指出的,这个库使用曲线secp256k1而不是secp256r1。secp256r1、prime256v1、INISTP-256都是由不同的标准组织为同一曲线(椭圆曲线密码体制(ECC)传输层安全密码套件(TLS))选择的不同名称。我将库更改为python-ecdsa,将代码更改为:

代码语言:javascript
复制
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")))

输出:

rMBgC0ismGdd5rd7n1L+LDsQ2UO5+cjBwPNYh+xBZvO6fKoJIfmfyNpxw+kxmyKWlK+55dF5eMH1u327DMJvvA==:rMBgC0ismGdd5rd7n1L-LDsQ2UO5-cjBwPNYh-xBZvO6fKoJIfmfyNpxw-kxmyKWlK-55dF5eMH1u327DMJvvA Base64Url: rMBgC0ismGdd5rd7n1L-LDsQ2UO5-cjBwPNYh-xBZvO6fKoJIfmfyNpxw-kxmyKWlK-55dF5eMH1u327DMJvvA Hash验证成功: True

但签名仍然无效。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-25 15:41:42

默认情况下,您使用的哈希库隐式地应用SHA1。也就是说,为了与ES256兼容,必须显式指定SHA256,并且必须使用未散列的JWT,例如:

代码语言:javascript
复制
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)))

一项可能的产出是:

代码语言:javascript
复制
Base64: Mr4/DF87ek66E2GcAc+2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA==
Base64Url: Mr4_DF87ek66E2GcAc-2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA
Hash verification succesfull: True

得到的签名令牌

代码语言:javascript
复制
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.Mr4_DF87ek66E2GcAc-2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA

然后可以使用此处使用的公钥在https://jwt.io/上成功验证。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66349140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档