Skip to content

Certificates for onionsites

Last updated on 2025-10-161.

Onion Services with already encrypted protocols

Onion Services have many interesting properties, including peer-to-peer connection encryption.

Any data flowing between two endpoints connected through an Onion Service is already encrypted.

This means one can create Onion Services such as websites (onionsite) by setting up a basic, unencrypted HTTP server atop the encrypted Onion Service protocol.

This simpler setup can be enough for many use-cases, but nowadays the need for encryption in the application protocol itself is growing fast, and sometimes it's even a requirement, besides providing defense in depth.

Examples include protocols using TLS, such as HTTPS, which is the peer-to-peer encrypted version of HTTP.

Validation models

Contrary to Onion Services, these other protocols might use distinct validation models:

  1. Onion Services encryption validation depends on whether one is connected to the right .onion address for a given service. The work of checking whether the address is the right one is usually done by the user -- except if Onion Discovery is used.
  2. Protocols built with TLS-based encryption, or any other using the X.509 standard, such as HTTPS, uses digital certificates relying on trusting in third parties called Certificate Authorities (CAs). The "trust" here is relative and consists basically in bundling the CAs' public keys in Operating Systems and applications such as web browsers: whenever you install a browser or a system, you'll automatically inherit trust that has been put in a given set of Certificate Authorities, like the Common CA Database. Validation succeeds when it's possible to verify that a given service certificate was signed by one of these trusted CAs.

Onion Services using HTTPS needs a certificate as a protocol requirement, but whether to use a CA-issued certificate or just a self-signed one is up to the service operator do decide.

Benefits of certificates for .onion

Using Onion Services with certificates might bring many benefits, and that's why it's even included in the onionsite checklist.

Certificate proposals

As of 2025-10, there are many proposed approaches to seamlessly integrate certificates with Onion Services, bridging the gap between the two distinct validation models mentioned above. Until these proposals are not available for production systems, operators have limited options.

One of these proposals is ACME for .onion domains, standardized as RFC 9799 and that brings automation to the whole certification lifecycle, but which as of 2025-10 still depends on implementation and deployment by CAs.

What to choose?

What to choose depends mostly on the protocol and desired properties. Some protocols may not offer a choice other than requiring certificates. Others, like HTTPS, allows for a range of possibilities.

Specifically for HTTPS, there's a comprehensive checklist section giving some pros and cons, as well as other advice when deciding whether to use HTTPS -- either with CA-issued or self-signed certificates -- or going just with HTTP.

In this guide, we'll adopt a two-stage approach:

  1. First, showcasing the tools for creating the encryption keys, a self-signed certificate and a Certificate Signing Request (CSR), which later allows upgrading to CA-issued certificates.
  2. Then, showing how to upgrade the previous setup with a CA-issued certificate.

The rest of this document is a general guide in how to setup and manage certificates, either self-signed or CA-issued.

Different key pair, not the .onion keys

It's worth noting that the key pair used for TLS-based protocols, including HTTPS, usually is not the same key pair from the .onion address, except if one is implementing specific approaches such as the Self-signed X.509 from .onion, which is uncommon as of 2025-10.

Per-application configuration

With TLS in general, including protocols such as HTTPS, certificates are not configured in the Tor daemon, but in the TLS-aware application like a web server like Apache, NGINX or Lighttpd.

Each of these applications have distinct configuration formats and procedures.

This guide is mostly about how to create and manage certificates, but does not cover how to install them in the service.

Cryptographic keys

Various algorithms are available in OpenSSL, but here we'll restrict ourselves with the ones allowed by the CA/B Baseline Requirements Section 6.1.5, that should work for HTTPS and other protocols using TLS:

For RSA key pairs the CA SHALL:

  • Ensure that the modulus size, when encoded, is at least 2048 bits, and;
  • Ensure that the modulus size, in bits, is evenly divisible by 8.

For ECDSA key pairs, the CA SHALL:

  • Ensure that the key represents a valid point on the NIST P-256, NIST P-384 or NIST P-521 elliptic curve.

No other algorithms or key sizes are permitted.

In short, we're restricted to either RSA (2024 bits onwards) or three types of ECDSA keys.

Certificate lifetime

Any certificate have a validity period, starting from the date of issuance and usually up to a specific date.

The optimal validity interval depends basically between the smallest interval possible to reduce the attack surface due to stolen encryption keys and the largest possible interval in order to minimize the work involved in the certificate issuance process.

Finding this optimal value was usually done by operators when setting up their services, and sometimes was bound to the maximum lifetime interval offered by CAs.

Although applications in general does not impose a maximum period for certificates they accept, there's no guarantee that certificates with long validity periods will be accepted by applications (example).

While there are no upper bound for self-signed certificates or certificates issued by custom/private CAs, mainstream CAs and browser vendors are reducing this interval as nowadays automated renewals allows for shorter life cycles.

From the CA/B Baseline Requirements Section 6.3.2,

  • Certificates issued until 2026-03-15 will have maximum validity period of 398 days.
  • Certificates issued between 2026-03-15 and 2027-03-15 will have a maximum validity period of 200 days.
  • Certificates issues between 2027-03-15 and 2029-03-15 will have a maximum validity period of 100 days.
  • From 2029-03-15 onwards, certificates will have a maximum validity period of 47 days.

In summary, the choices are rather limited here:

  • When using a self-signed certificate, or a certificate issued by a CA no adhering to the CA/B Baseline Requirements, there's no upper limit for the expiration date, but long lifetimes may not be accepted by some applications. As of 2025-10, validity periods of 365 days should work for most, if not all, cases.

  • When using a CA-issued certificate adhering to the CA/B Baseline Requirements, expiration will be limited to the above-mentioned periods.

Self-signed certificates and Certificate Signing Requests

The first step into adding TLS/HTTPS support to your Onion Services involves creating a key pair and a self-signed certificate.

As as bonus, it's worth also creating a CSR which can eventually be sent to a CA in order to get a certificate easily validated in standard tools such as web browsers.

Using Onionspray

Onionspray is a HTTPS proxy for existing websites, and one of the quickest ways to get started with onionsites.

Onionspray's certificate management (including self-signed certs and CSRs) is detailed here.

Using Oniongroove

Oniongroove is the next generation tool for managing onionsites, and handles self-signed certificates automatically, but it's still (as of 2025-10) under development.

Using Onionmine

The Onionmine tool can be used to quickly create self-signed certificates with the recommended defaults and without the need to dive into specifics.

Using OpenSSL

Using OpenSSL (packages) directly, self-signed certs and CSRs can be generated in a number of ways.

There are many tutorials, forum posts, Q&A, documentations and possibilities out there, each one using different commands, options and configurations for OpenSSL.

Here we'll offer a three-step process with recommended settings and for the example Onion Service address exav2agnwayz4hxbm2elifyn25ivey7pg7glg676nz2udsobbvsihkad.onion.

1. Creating a key pair

You can create a ECDSA key pair, such as P-384, with openssl ecparam:

openssl ecparam \
        -genkey \
        -out privatekey.pem \
        -name secp384r1

Or you can create a RSA-based key pair with openssl genrsa:

openssl genrsa \
        -out privatekey.pem \
        4096

Note that this pair is not associated with the .onion address yet: this is done in the next steps.

2. Creating a CSR

A CSR can be created with openssl req:

ONION_ADDR="exav2agnwayz4hxbm2elifyn25ivey7pg7glg676nz2udsobbvsihkad.onion"
openssl req \
        -new \
        -sha384 \
        -nodes \
        -key privatekey.pem \
        -subj "/CN=$ONION_ADDR" \
        -addext "subjectAltName=DNS:$ONION_ADDR,DNS:*.$ONION_ADDR" \
        -out csr.pem

Wildcard SAN in the CSR by default

The command above adds a wildcard as a Subject Alternative Name (SAN) by default in the resulting CSR, which should be harmless if a certificate being purchased/requested won't have a wildcard, as it's the CA's job to parse and remove SANs that does not belong to an order).

The rationale behind that is discussed at tpo/onion-services/onionmine#39.

If you find problems with a CA not accepting your CSR because of that -- like if you're purchasing a regular, non-wildcard certificate, but your CSR has a wildcard in the subjectAltName -- try changing the command line by removing ,DNS:*.$ONION_ADDR from the subjectAltName.

3. Creating a self-signed certificate

With the resulting CSR, it's now possible to request a certificate in a CA. But in the case you want a self-signed certificate, go ahead with by running openssl req again:

openssl req \
        -new \
        -x509 \
        -sha384 \
        -days 365 \
        -nodes \
        -key privatekey.pem \
        -subj "/CN=$ONION_ADDR" \
        -addext "subjectAltName=DNS:$ONION_ADDR,DNS:*.$ONION_ADDR" \
        -out self-signed.crt

The command above generates a CSR for a wildcard certificate.

To get a CSR just for the base .onion domain, remove the ,DNS:*.$ONION_ADDR from the subjectAltName option.

To add subdomains into the CSR, add something like ,DNS:mysubdomain.$ONION_ADDR in the subjectAltName option.

Single domain or wildcard certificate

When creating the self-signed certificate and the CSR, you'll need to decide whether to go for a single domain or a wildcard certificate. This is done by adding one or more Subject Alternative Names (SANs) in the CSR.

This depends mostly on your requirements.

For a Onion Service using only the top-level domain such as exav2agnwayz4hxbm2elifyn25ivey7pg7glg676nz2udsobbvsihkad.onion, a single domain in the subjectAltName option will suffice.

But if you need additional subdomains, then a wildcard is needed.

If unsure, try out the wildcard self-signed certificate.

CA-issued certificates

Now that you generated a key pair to be used in protocols such as TLS (including HTTPS) and a CSR, you're halfway from getting a CA-issued certificate.

CAs may expose .onion addresses in CT Logs

Most, if not all, mainstream CAs, add entries to CT Logs during the certificate issuance process, this this is becoming mandatory by major vendors.

This means the .onion address will be publicly known.

If this is a concern, consider other existing options.

Choosing a Validation Level

There are a few Validation Levels available for CA-issued .onion certificates:

Choosing a Certificate Authority

As of 2025-10, the following Certificate Authorities supports .onion domains:

Currently, none of them offers free-of-charge certificates, and purchasing requires the use of credit cards or other accepted payment methods.

Proving possession

A CSR is not enough for getting a CA-issued certificate, as it only provides information on the cryptographic keys to be used in protocols such as TLS (including HTTPS), which usually aren't the same as the .onion keys.

Therefore, an additional verification step is needed to ensure the requester in fact possesses the private .onion identity key.

Domain Validation

For DV certificates, the available methods are detailed in the CA/B Baseline Requirements Appendix B - Item 2:

  • Certificate Request signed using the .onion service’s private key (onion-csr).
  • Agreed-Upon Change to Website v2.
  • Agreed-Upon Change to Website - ACME.
  • TLS Using ALPN.

Refer to the CA/B Baseline Requirements for a description of each method. Here we'll only cover the practical details involved on the methods known to be in use.

Using onion-csr

The onion-csr method is the only one that works for all use-cases, including non-HTTPS applications and even for those not relying on TLS.

In summary, by this method the CA provides a nonce -- which in this case is basically a random string -- to be signed by Onion Service operator using the .onion identity key and returned to the CA in the format of an additional CSR.

In theory, any cryptography software capable of handling key types used by Onion Services (such as OpenSSL) could be used to sign the nonce and create the additional CSR.

But since Onion Service keys are stored in custom formats, specialized tools needs to be used:

Using Agreed-Upon Change to Website v2

The CA might offer you the option to post a secret key at a particular URL, useful if your application is an onionsite.

The message will read something like:

Place the file FILENAME to http://ONIONADDRESS.onion/.well-known/pki-validation/

... and the CA will offer you a file to download and put in your webroot of the HTTP site:

  1. If you're using Onionspray, this file is managed through a configuration setting.
  2. If you're managing the webserver yourself, create a directory named .well-known/pki-validation/ in your webroot and put the validation file in there.

Verify that it is possible to download the file using a Tor-aware client like Tor Browser.

After some time, the validation should finish and you get an email.

Using Agreed-Upon Change to Website - ACME

As of 2025-10, we're not aware of any CA doing domain-validation for .onion using this method. Please let us know otherwise.

TLS using ALPN

As of 2025-10, we're not aware of any CA doing domain-validation for .onion using this method. Please let us know otherwise.

Extended Validation

Procedures for EV certificates involves additional checks and are beyond the scope of this document. Please following the guidance from a Certificate Authority when request such type of certificate.

Downloading and installing the certificate

After certificate issuance, the CA will offer you several files to download. What to download and use really depends on your application.

If you're using Onionspray, follow [these instructions][].

Usually, an unencrypted "PEM Bundle" is the right choice and contains both the certificate and some parent certs in the chain of trust.

If the PEM Bundle is available, download this file and copy it to your application server.

Non-bundle might work

Using just the certificate for your service, without bundling other certs, might or might not work, depending on the CAs available for your application.

In general, it's most guaranteed to use the PEM Bundle.

If the CA does not provide this file ready to use, you'll have to concatenate these certificates yourself.

Do not add the private key

When building the PEM Bundle certificate file, DO NOT INCLUDE THE TLS PRIVATE KEY.

Testing TLS connections (including HTTPS) over .onion

With a Tor-enabled application

The simplest way to test your TLS-enabled Onion Service is by accessing it though a Tor-enabled application, which allows to spot most common problems.

For the case of HTTPS onionsites, a tool such as Tor Browser might be enough.

It's also worth trying curl, which supports HTTPS and many other protocols:

ALL_PROXY=socks5h://127.0.0.1:9050 curl --verbose https://v236xhqtyullodhf26szyjepvkbv6iitrhjgrqj4avaoukebkk6n6syd.onion/

With OnionSec

The OnionSec application has a web interface and a command line to test HTTPS connections and certificates.

With Onionprobe

Onionprobe is a tool for testing and monitoring the status of Onion Services, checking whether connections uses CA-issued certificates as well as certificate expiry dates.

Onionprobe has ready-to-use configurations and also a standalone monitor mode, which can be used to build dashboards displaying certificate issues as well as sending notifications about expiring certificates.

Upcoming non-HTTP support for Onionprobe

As of 2025-10, Onionprobe only works for HTTP and HTTPS endpoints, so it's not suitable for testing certificates in protocolos other than HTTPS.

This is a current limitation, which is tracked at issue tpo/onion-services/onionprobe#23.

Reference onionsites

Some reference onionsites are available to help diagnosing issues either with clients or services:

Development

Development and experimentation with certificates for Onion Services is detailed in a specific page.

Notes


  1. This document was written in the scope of ticket tpo/onion-services/ecosystem#14