--- title: Strong TLS certificates with acme.sh subtitle: 384-bit of https lang: en slug: "acme-sh-tls-cert" createdAt: "2022-06-08T14:24:06.000Z" excerpt: Real cert have curves. tags: ["security"] type: snippets --- ## Disclaimer I'm, in absolutely no regards, a security expert. I just fancy shiny new things of the interwebs. This is why I've switched my default TLS certificates to use elliptic curve cryptography (ECC) instead of RSA. Now I have a sweet 100/100 on [tls.imirhil.fr](https://tls.imirhil.fr/) You can learn (far) more by reading [this topic](https://crypto.stackexchange.com/questions/1190/why-is-elliptic-curve-cryptography-not-widely-used-compared-to-rsa) and its linked resources. ## Requirements ### Installing acme.sh For automation and ease of use purposes, I'm using [acme.sh](https://github.com/acmesh-official/acme.sh) ```bash # for using standalone mode, you might have to install as sudo curl https://get.acme.sh | sh -s email=mail@domain.tld ``` ### Changing default authority By default, acme.sh uses ZeroSSL to sign certificates. We need to change this to Let's Encrypt because according to acme.sh, they're the only ones offering ECC capabilities. ```bash acme.sh --set-default-ca --server letsencrypt ``` ## Using your DNS api If available, the easiest way to issue a certificate is to use the DNS api of your DNS provider. acme.sh supports [a lot](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) of DNS providers. ### Define an api key Follow the [docs](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for your DNS provider, usually: ```bash export PROVIDER_Key="YOUR_API_KEY" ``` ### Issue the cert ```bash acme.sh --issue -d domain.tld --dns dns_provider --keylength ec-384 ``` ## Using standalone mode If you don't have access to the DNS provider, we can use the standalone mode to spin up a temporary web server that will handle all the verifications. Port `80` must be free. ```bash acme.sh --issue --standalone -d domain.tld --keylength ec-384 ``` ## Examples ### Multi domains standalone ```bash acme.sh --issue --standalone -d domain.tld -d www.domain.tld -d subdomain.domain.tld --keylength ec-384 ``` ### Wildcard domain DNS ```bash acme.sh --issue -d domain.tld -d '*.domain.tld' --dns dns_provider --keylength ec-384 ``` ## Next steps The ECC certificate alone will not grant you a high/perfect score. ### TLS version Limit TLS version to 1.2 and 1.3 (or just 1.3 as there is only a [5% compatibility gap](https://caniuse.com/?search=tls%201.) with 1.2). ### HSTS Use the [strict transport security](https://scotthelme.co.uk/hsts-the-missing-link-in-tls/) header. ``` Strict-Transport-Security: max-age=31536000; includeSubDomains ``` ### Cipher suite Use recent and strong ciphers. This is where my knowledge hits its limit… I'm having a really hard time understanding what to use and why. I've based my initial choices of ciphers on [this list](https://tls.imirhil.fr/ciphers), cross referencing it with (older?) [browser compatibility](https://tls.imirhil.fr/suite). I then asked [Aeris](https://twitter.com/aeris22), the creator of [tls.imirhil.fr](https://tls.imirhil.fr), about it and he advised me to use the following: ``` ECDHE+AES:ECDHE+CHACHA20 ``` In order to achieve a perfect score, we can be a little more restrictive with: ``` ECDHE+AES256:ECDHE+CHACHA20 ```