Skip to content

Crypto

lacme.crypto

Cryptographic operations for ACME (RFC 8555).

Pure functions for base64url encoding, EC P-256 key generation, JWK/JWS construction, CSR generation, and key authorization computation.

account_thumbprint

account_thumbprint(account_key: EllipticCurvePrivateKey) -> str

Compute the JWK Thumbprint of the account key's public key.

b64url_decode

b64url_decode(s: str) -> bytes

Decode a base64url string (with or without padding) to bytes.

b64url_encode

b64url_encode(data: bytes) -> str

Encode data to a base64url string without padding.

generate_csr

generate_csr(key: EllipticCurvePrivateKey, domains: Sequence[str | IPv4Address | IPv6Address]) -> bytes

Generate a DER-encoded CSR with domains as SANs.

CN is set to the string representation of the first identifier. Strings are treated as DNS names; :class:~ipaddress.IPv4Address and :class:~ipaddress.IPv6Address objects become IP SANs.

generate_ec_key

generate_ec_key() -> ec.EllipticCurvePrivateKey

Generate a new EC P-256 private key.

jwk_thumbprint

jwk_thumbprint(jwk: dict[str, str]) -> str

Compute the JWK Thumbprint per RFC 7638.

Only the required members for the key type are included in the canonical JSON (RFC 7638 §3.2). For EC keys these are crv, kty, x, y in lexicographic order.

Returns a base64url-encoded SHA-256 digest.

jws_encode

jws_encode(payload: bytes, key: EllipticCurvePrivateKey, *, nonce: str | None = None, url: str, kid: str | None = None) -> dict[str, Any]

Create a JWS in Flattened JSON Serialization.

Protected header always contains alg (ES256) and url. nonce is included when provided (omit for key rollover inner JWS). If kid is None the header includes jwk (for newAccount). Otherwise it includes kid (for all subsequent requests).

An empty payload (b"") signifies POST-as-GET: the "payload" field in the returned dict will be the empty string "".

jws_encode_hmac

jws_encode_hmac(payload: bytes, mac_key: bytes, *, alg: str = 'HS256', kid: str, url: str) -> dict[str, Any]

Create a JWS in Flattened JSON Serialization using HMAC.

Used for External Account Binding (RFC 8555 §7.3.4). Protected header contains alg, kid, and url only.

Parameters:

Name Type Description Default
payload bytes

Raw bytes to sign (typically a serialized JWK).

required
mac_key bytes

Decoded HMAC key (raw bytes, not base64url-encoded).

required
alg str

MAC algorithm identifier. Only "HS256" is supported.

'HS256'
kid str

External account key identifier (from the CA).

required
url str

ACME newAccount URL.

required

Raises:

Type Description
ValueError

If alg is not "HS256".

key_authorization

key_authorization(token: str, account_key: EllipticCurvePrivateKey) -> str

Compute token + '.' + base64url(Thumbprint(accountKey)).

pem_to_der_certificate

pem_to_der_certificate(cert_pem: bytes | str) -> bytes

Convert a PEM-encoded certificate to DER format.

If the PEM contains a chain, only the first (leaf) certificate is converted.

private_key_from_pem

private_key_from_pem(pem_data: bytes, password: bytes | None = None) -> ec.EllipticCurvePrivateKey

Deserialize a PEM-encoded private key.

private_key_to_pem

private_key_to_pem(key: EllipticCurvePrivateKey, password: bytes | None = None) -> bytes

Serialize key to PEM format, optionally encrypted.

public_key_to_jwk

public_key_to_jwk(key: EllipticCurvePublicKey) -> dict[str, str]

Convert an EC public key to a JWK dict.

Returns {kty, crv, x, y} with base64url-encoded fixed 32-byte coordinates. Per erratum 7565, leading zeros in the fixed-length ECDSA coordinate fields are preserved.