ยท All Snippets

Let's Encrypt PEM Account Key Setup

Let’s Encrypt needs an account key for verification of domains and requesting the signed certificate. We register an email for important announcements with the account key and want to back it up, as it allows us to manage and revoke certificates. From our local MacOS machine we do

brew install certbot
mkdir cfg letsencrypt logs
certbot register --config-dir cfg --work-dir letsencrypt --logs-dir logs

This creates a JSON formated private key under cfg/accounts/.../private_key.json. There is a simple Go cli tool posted here, to convert the JSON key to the PEM format with the package. I’ve pasted a minor variation of the tool here for posterity and reference. tool via

package main

import (


func main() {
        if len(os.Args) != 2 {
                fmt.Printf("Usage: %v private_key.json\n", os.Args[0])

        pkBuf, err := ioutil.ReadFile(os.Args[1])
        if err != nil {

        var k jose.JSONWebKey
        if err := k.UnmarshalJSON(pkBuf); err != nil {

        switch p := k.Key.(type) {
        case *rsa.PrivateKey:
                        Type:  "RSA PRIVATE KEY",
                        Bytes: x509.MarshalPKCS1PrivateKey(p),
                panic("Unknown key format" + reflect.TypeOf(p).String())

We can then convert the key format

go run letsencryptpem cfg/accounts/.../private_key.json

and copy it to our server

scp account.pem

on the server we copy it into place

doas cp account.pem /etc/acme/letsencrypt.pem

and can follow using it with the acme-client for an httpd setup.

Last modified on Saturday, Jul 3, 2021.
Go back