By John Hanley, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.
In this multipart article, we will discuss about SSL certificates in detail to remove any doubts on this topic. We will learn how to use the Let's Encrypt ACME version 2 API using Python to develop software that can create, install, renew and revoke SSL certificates for Alibaba Cloud. Although we have used Alibaba Cloud products for the tutorial, the same principles apply to any computing service that supports X.509 SSL certificates.
In Part 3, we explained about ACME endpoints, and talked about getting the ACME directory, creating an ACME account, and retrieving your ACME account information.
In this part, we will explain in detail on how to construct ACME requests and sign the JWS payload.
Let's look at an example to create a new account. This pseudo-code example shows the HTTP POST, the HTTP headers and the HTTP body. The "based64_encode" is not actually part of the HTTP body but shows that the code should based64 encode the data before sending to the ACME server.
POST /acme/new-account HTTP/1.1
Host: acme-staging-v02.api.letsencrypt.org
Content-Type: application/jose+json
{
"protected": base64_encode({
"alg": "ES256",
"jwk": {...},
"nonce": "6S8IqOGY7eL2lsGoTZYifg",
"url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-acct"
}),
"payload": base64_encode({
"termsOfServiceAgreed": true,
"contact": [
"mailto:cert-admin@example.com",
"mailto:admin@example.com"
]
}),
"signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I"
}
An ACME request is encapsulated in a JSON Web Signature (JWS) object.
The JWS object consists of three parts. The JWS Protected Header, the API command parameters (payload) and the signature. We will cover each part below. Each part is separately base64 encoded and then combined into one JSON object.
{
"protected": base64_encode(jws_protected_header),
"payload": base64_encode(payload),
"signature": based64_encode(signature)
}
Within the JWS object is the JWS Protected Header. The JWS Protected Header contains the following fields:
Field | Description |
---|---|
alg | Algorithm. This is the MAC based algorithm used to sign the request. Supported algorithms are ES256 and RS256. Reference RFC 7518. In these examples we will be using RS256 (RSASSA-PKCS1-v1_5 using SH-256). Simplified description: RS256 means signing with an RSA private key and validating with the corresponding RSA public key. |
jwk | JSON Web Key. The JWK is used for all requests that are not signed using an existing account. For example: "New Account". The JWK is a JSON object that we will cover later in this article. |
kid | Key ID. The KID is used for all requests that are signed using an existing account. For example, Get Account Information. |
nonce | Nonce. A unique value used to prevent replay attacks. This value is returned by the NewNonce API and in the response header "Replay-Nonce" after each successful ACME API call. The Replay-Nonce value is used for the next ACME API call. |
url | URL. This header parameter encodes the URL to which the client is directing the request. Consult each ACME API for the required value. |
The "jwk" and "kid" fields are mutually exclusive. Servers MUST reject requests that contain both.
The ACME API will specify using one or the other.
The JWK parameters vary based upon the type of cryptographic signing. For the examples in this series we are using RSA key pairs.
Field | Description |
---|---|
e | Public Exponent. This is the public exponent from the RSA keypair. |
kty | Key Type. The method used to sign the JWS. The value is RSA when using RSA keypairs. Reference RFC 7638 for detailed information. |
n | Modulus. This is the modulus from the RSA keypair. For a 2048-bit key, the field "n" value is 256 octets in length when decoded. |
{
"e": base64_encode(public_exponent),
"kty": "RSA",
"n": base64_encode(modulus),
}
The payload contains the API call parameters. These will be different for each API. The contents of the payload json object are base64 encoded. The following examples shows the payload for the New Account API. There are two parameters: "termsOfServiceAgreed" and "contact". The payload is part of the JSON Web Signature (JWS) included in the HTTP body.
"payload": base64_encode({
"termsOfServiceAgreed": true,
"contact": [
"mailto:cert-admin@example.com",
"mailto:admin@example.com"
]
})
The signature is a SHA-256 message digest using the RSA private key. The ACME server validates the signature using the corresponding public key.
def sign(data, keyfile):
""" Create the ACME API Signature """
# Load the RSA Private Key from the file (RSA PKCS #1)
pkey = load_private_key(keyfile)
# Create the signature
sig = crypto.sign(pkey, data, "sha256")
return sig
The above demonstrates how the ACME API system works.
In the next and final part, we will examine how to perform DNS validation and how to create and modify DNS server resource records to support ACME DNS validation.
Understanding Alibaba Cloud DataV - A Powerful and Accessible Data Visualization Tool
2,599 posts | 762 followers
FollowAlibaba Clouder - June 27, 2018
Alibaba Clouder - June 25, 2018
Alibaba Clouder - June 26, 2018
Nguyen Phuc Khang - June 4, 2024
Nguyen Phuc Khang - June 4, 2024
Alibaba Clouder - July 1, 2020
2,599 posts | 762 followers
FollowAPI Gateway provides you with high-performance and high-availability API hosting services to deploy and release your APIs on Alibaba Cloud products.
Learn MoreA scalable and high-performance content delivery service for accelerated distribution of content to users across the globe
Learn MoreYou can use Certificate Management Service to issue, deploy, and manage public and private SSL/TLS certificates.
Learn MoreMore Posts by Alibaba Clouder
282604745917283389 December 28, 2018 at 1:33 pm
Where is the link to Part V