Reputation: 21
I'm trying to code an API client, the API authentication need a signing the payload using ed25519
according to JWT specification.
The payload is:
{"key": "cnc6666666666666", "iat": 1599999999}
The Seed (also called Private Key, which can be used to calculate the Signing Key) of ed25519
is:
"CNC88888888888888888888888888888"
The target(JWT Spec) result should be:
eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpYXQiOjE1OTk5OTk5OTksImtleSI6ImNuYzY2NjY2NjY2NjY2NjYifQ.RJzhQwRI6g0YZg-Mh201G7aEGcpxm8vN8wf-rgpK6UySeMKRgUHzZV6WLxc93PptrKNb4CLW8XQo48OYR-stDw
I've followed the method showed here. The generateSignature
function is what I've tried.
This method is not working for python3, and ed25519
is not officially supported by JWT, so the algorithm is customized implemented in the above sample.
Any help is much appreciated.
Upvotes: 2
Views: 1242
Reputation: 31
Usage: Issuing and using credentials An Ed25519 public/private key pair needs to be created, for example using the Python cryptography package:
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))
The issuer of credentials would use the private key to create a JWT for a database user, such as in the below Python example for the database user my_user for the next 24 hours.
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)
Upvotes: 3