# -*- coding: utf-8 -*-
auth_url = "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/172480296"
account_url = "https://acme-staging-v02.api.letsencrypt.org/acme/acct/17092284"
key_dict = {
"y": "...",
"x": "...",
"crv": "P-256",
"kty": "EC",
"d": "..."
}
import requests
import json
from jose import jws
from pprint import pprint as pp
# Get a nonce
resp = requests.head('https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce')
pp(resp.headers)
replay_nonce = resp.headers['Replay-Nonce']
print('Nonce is: {}'.format(replay_nonce))
# Generate a key
# Create the protected and payload structures
protected_header = {
"alg": "ES256",
"nonce": replay_nonce,
"url": auth_url,
# "jwk": key.export(private_key=False, as_dict=True)
"kid": account_url
}
payload = ""
protected_enc = json.dumps(protected_header, sort_keys=True)
payload_enc = ""
print("protected: {}".format(protected_enc))
print("payload: {}".format(payload_enc))
# Sign the JWS
signed_parts = jws.sign(
payload.encode("utf-8"),
key_dict,
headers=protected_header,
algorithm=jws.ALGORITHMS.ES256,
).split(".")
signed = {
"protected": signed_parts[0],
"payload": signed_parts[1],
"signature": signed_parts[2],
}
print('=======req=======')
pp(signed)
# Send the JWS to the ACME server
session = requests.Session()
session.headers.update({'Content-Type': 'application/jose+json'})
resp = session.post(
url=auth_url,
data=signed,
)
print('========response========')
print(resp.headers)
pp(resp.json())
OUTPUT:
=======req=======
{'payload': u'',
'protected': u'eyJhbGciOiJFUzI1NiIsImtpZCI6Imh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xNzA5MjI4NCIsIm5vbmNlIjoiMDAwMzRqZXptdEtSN1N5akF0Q1psNXd0RDlKd1pkZ1V0dXZ0czl2WWNMdXpXejAiLCJ0eXAiOiJKV1QiLCJ1cmwiOiJodHRwczovL2FjbWUtc3RhZ2luZy12MDIuYXBpLmxldHNlbmNyeXB0Lm9yZy9hY21lL2F1dGh6LXYzLzE3MjQ4MDI5NiJ9',
'signature': u'9N-E9aMsH2gyNcjUkyYT52CWphyjHDO2_BJr-Twduo3UVjhPko9F_RSTixN74mrnKWoCdByhxQvY4NUnMWtaBw'}
========response========
{'Content-Length': '108', 'Server': 'nginx', 'Connection': 'keep-alive', 'Link': 'https://acme-staging-v02.api.letsencrypt.org/directory;rel="index"', 'Cache-Control': 'public, max-age=0, no-cache', 'Date': 'Tue, 15 Dec 2020 06:51:41 GMT', 'Content-Type': 'application/problem+json', 'Replay-Nonce': '0003JyPk5Js9L2c1tH4Hwq0BAOUb_BFStbocQ1agEil2kgI'}
{u'detail': u'Parse error reading JWS',
u'status': 400,
u'type': u'urn:ietf:params:acme:error:malformed'}