如何使用python将ed25519算法实现到jwt中?

Posted

技术标签:

【中文标题】如何使用python将ed25519算法实现到jwt中?【英文标题】:How to implement ed25519 algorithm into jwt using python? 【发布时间】:2019-08-16 21:07:57 【问题描述】:

我正在尝试编写 API 客户端,API 身份验证需要根据 JWT 规范使用ed25519 对有效负载进行签名。

有效载荷是:

"key": "cnc6666666666666", "iat": 1599999999

ed25519的Seed(也叫Private Key,可以用来计算Signing Key)是:

"CNC88888888888888888888888888888"

目标(JWT Spec)结果应该是:

eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpYXQiOjE1OTk5OTk5OTksImtleSI6ImNuYzY2NjY2NjY2NjY2NjYifQ.RJzhQwRI6g0YZg-Mh201G7aEGcpxm8vN8wf-rgpK6UySeMKRgUHzZV6WLxc93PptrKNb4CLW8XQo48OYR-stDw

我已按照here 显示的方法进行操作。 generateSignature 函数是我尝试过的。

此方法不适用于python3,而ed25519没有被JWT官方支持,所以在上面的示例中自定义实现了算法。

非常感谢任何帮助。

【问题讨论】:

欢迎来到 Stack Overflow。请考虑taking the tour。如果您在这里learn how to ask questions,用户更有可能提供帮助。请针对您的具体问题提供minimal, complete, and verifiable example。 【参考方案1】:

用途:颁发和使用凭证 需要创建 Ed25519 公钥/私钥对,例如使用 Python 加密包:

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, PublicFormat

private_key = Ed25519PrivateKey.generate()
print(private_key.private_bytes(encoding=Encoding.PEM, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption()))
print(private_key.public_key().public_bytes(encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo))

凭证的颁发者将使用私钥为数据库用户创建 JWT,例如在下面的 Python 示例中为数据库用户 my_user 在接下来的 24 小时内创建一个 JWT。

from base64 import urlsafe_b64encode
import json
import time
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key

def b64encode_nopadding(to_encode):
    return urlsafe_b64encode(to_encode).rstrip(b'=')

private_key = load_pem_private_key(
    # In real cases, take the private key from an environment variable or secret store
    b'-----BEGIN PRIVATE KEY-----\n' \
    b'MC4CAQAwBQYDK2VwBCIEINQG5lNt1bE8TZa68mV/WZdpqsXaOXBHvgPQGm5CcjHp\n' \
    b'-----END PRIVATE KEY-----\n', password=None, backend=default_backend())
header = 
    'typ': 'JWT',
    'alg': 'EdDSA',
    'crv': 'Ed25519',

payload = 
    'sub': 'my_user',
    'exp': int(time.time() + 60 * 60 * 24),

to_sign = b64encode_nopadding(json.dumps(header).encode('utf-8')) + b'.' + b64encode_nopadding(json.dumps(payload).encode('utf-8'))
signature = b64encode_nopadding(private_key.sign(to_sign))
jwt = (to_sign + b'.' + signature).decode()
print(jwt)

【讨论】:

以上是关于如何使用python将ed25519算法实现到jwt中?的主要内容,如果未能解决你的问题,请参考以下文章

一文说明白ECDSA spec256k1 spec256r1 EdDSA ed25519千丝万缕的关系

如何以通过 ed25519 识别的用户身份使用 MYSQL Workbench 连接到 MariaDB (10.5.8)?

区块链中的Ed25519

如何使用 Bouncy Castle 创建与 OpenSSH 兼容的 ED25519 密钥?

ANFS | ED25519密钥体系 技术一小步 行业发展一大步

使用ED25519算法生成SSH密钥,解决git clone报错:early EOF fetch-pack: invalid index-pack output