我正在尝试手动创建ES256 JWT令牌。我有一个用python编写的小脚本,它对使用ecdsa python的sha256哈希进行签名。但签名在jwt上无效。木卫一。
繁殖步骤:
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9。EYJZDWIixMJ0Nty3ODKwiiBmFtzSi6IkPvAg4GrG9LiiWiyWrTaw4IonrydWusimlHDCI6MTuxNjizotaYMn0
FFC89E33091FFDD3C61798A0A74BF7C2D1A6FD231A6CB519F33952F7696BBE9F
openssl ec-inec_private.pem-noout-text
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:Meqcifip4iozghzgfdcpx6fvxjtb nrxdvhotqwdc5vu8z4eaibnalfghqdao3nctqimpahf IHzxk8em OMMHrJkPOhA==
Base64Url:MEQCIFIP4IOZGHZGFDCX6FVXJTB-NRXDVHOTQWDC5VU8Z4EAIBNALFGHQDAO3NCTQIMPAHF-IHzxk8em-OMMHrJkPOhA
哈希验证成功:True
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9。EYJZDWIixMJ0Nty3ODKWIIbMfTzSi6IkPvAg4GrG9LiiWiyWrTaw4IonrydWusimlHDCI6mtuxNjizotaymn0。MEQCIFIp4IOZGHZGFDCx6FVXJTB-NRXDVHOTQWDC5VU8Z4EAIBNALFGHQDAO3NCTQIMPAHF-IHzxk8em-OMMHrJkPOhA
钥匙:
公众:
-----开始公钥------MFKWEWYHKOZJ0CAQYIKOZJ0DAQCDQGAE1TG2UVIMDFWKTEIDWEHNYBQSW/0 UOYCVX4Z7ROUIGYRVGFPSJBAIV70SUYPMBL0AUEBOXIVTCLCME6SDEQ=----结束公钥-----
私人:
-----BEGIN EC私有密钥-----MHcCAQEEIJfChy9fKFItzqcb8DKBm 2oH0YTZ7N61SQpyABgVZANoAoGCCqGSM49 AwEHoUQDQgAE1TG2uvIMdfWkteiDWeHNYbQNSW/0uoYcvX4Z7ROUIgYRvgfpsjBa Iv70SuYpmBLwl0AuEBoXIVTCclCme6SdEQ== -----END EC私有密钥-----
我知道有很多jwt签名python库,但是使用它是为了理解jwt令牌是如何创建的。
编辑:
Secp256r1|prime256v1|NIST P-256都是由不同的标准组织为同一曲线选择的不同名称(椭圆曲线密码学(ECC)安全传输层协议密码套件(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:RMB0ISMGDD5RD7N1L-LDsQ2UO5-cjBwPNYh-xBZvO6fKoJIfmfyNpxw-kxmyKWlK-55dF5eMH1u327DMJvvA
哈希验证成功:True
但是签名仍然无效。
您正在隐式使用哈希的库,默认情况下应用SHA1。即,为了与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
生成的签名令牌
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.Mr4_DF87ek66E2GcAc-2H3ulHplCnxygz65h9dkdvm8QsZBbm2N5EjIgyiWsynza9zCGjjnzBUiXYvij9LLikA
然后可以在上成功验证https://jwt.io/使用这里使用的公钥。
我正在使用Azure AD对spring boot应用程序进行用户身份验证。我创建了一个应用程序来获取登录用户的访问令牌(令牌创建者应用程序)。在此应用程序中,“/token”API从@RegisteredAuth2AuthorizedClient读取访问令牌,并返回与响应相同的令牌。 然后,我必须使用返回的令牌作为RESTAPI的承载令牌,用于具有相同客户端id和相同配置的另一个应用程序。 但当
我正在JWT(JSON Web令牌)方案的帮助下实现一个登录系统。基本上,在用户登录/登录之后,服务器签署一个JWT并将其传递给客户机。 然后,客户机返回每个请求的令牌,服务器在发送回响应之前验证令牌。 这是你所期望的,但是我在这个过程的逻辑上遇到了一些问题。从我读过的所有数学文章来看,RSA签名似乎使用非对称密钥进行签名。由于公钥(顾名思义)是向客户机公开的,而私钥保留在服务器上,因此使用发送给
我正在使用谷歌KMS(https://cloud.google.com/kms/)使用非对称签名密钥对节点中的JSON Web令牌(jwt)进行签名。js应用程序。 我能够创建标头和有效载荷,并与谷歌KMS nodejs库(https://github.com/googleapis/nodejs-kms)我可以签署令牌。 但似乎生成的令牌无效。 事实上,我正在执行以下步骤来生成令牌: 将jwt头定
这是一场噩梦。我在使用jwt验证Azure访问令牌签名时遇到问题。木卫一。不管我做什么,答案总是无效的签名。 有人能帮忙吗? 我的步骤: 我从MSALJava应用示例(msal-java-webapp-samp)生成了一个Token Id和Access Token。 我从我的Azure访问令牌中获得访问令牌头中的孩子访问。 我访问
我想用JSON Web签名(JWS)做一个项目,并且我想发送用于签名的证书的公钥,以便在收到该公钥后可以验证消息。我正在使用Ninbus JOS JWT库。我可以对JSON对象进行签名,并且可以看到公钥,但是我无法正确验证它。代码如下: 公钥是:“Sun RSA公钥,2048位”,但当我从JWK(_RSA公钥2)获得它时,我得到了“Sun RSA公钥,3696位”,我不知道为什么。 谢谢
我目前正在使用Vapor开发Swift后端。我的iOS客户端使用新的iOS 13功能“使用Apple登录”。当用户登录时,我会得到一个身份令牌(访问令牌),这是一个由Apple签名的有效JWT令牌。这将在所有正在进行的通信中发送到服务器,以验证服务器提供的某些路由。 在服务器上,我想通过验证令牌签名来验证发送的令牌是否确实由Apple签名,并且不是由某些恶意用户专门创建的。Apple提供了一个HT