# Configuring SSL/TLS for qBittorrent Connections: Web UI HTTPS and Torrent Encryption Guide

> Secure your qBittorrent with SSL/TLS. Learn to configure HTTPS for the Web UI and enable torrent encryption for safer downloads. Protect your qBittorrent connections today.

- Repository: [qBittorrent project/qBittorrent](https://github.com/qbittorrent/qBittorrent)
- Tags: how-to-guide
- Published: 2026-05-05

---

**qBittorrent supports SSL/TLS in two distinct modes: HTTPS encryption for the Web UI via `Http::Server::setupHTTPS()`, and per-torrent TLS parameters through the `BitTorrent::SSLParameters` struct, with both utilizing `Utils::SSLKey::load()` for automatic EC/RSA key detection.**

Enabling **SSL/TLS for qBittorrent connections** protects both your management interface and peer-to-peer traffic. The qbittorrent/qBittorrent repository implements these features through Qt's `QSslSocket` infrastructure and libtorrent's encrypted peer support. This guide explains the implementation details, configuration paths, and API methods for securing your qBittorrent deployment.

## HTTPS for the Web UI

The Web UI encryption begins in [`src/base/http/server.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/http/server.cpp) with the `Http::Server::setupHttps()` method. When you enable HTTPS in *Options → Web UI* or via command-line flags, the application loads your PEM-encoded certificate and private key through `Utils::Net::loadSSLCertificate()` and `Utils::SSLKey::load()`.

```cpp
// src/base/http/server.cpp
bool Server::setupHttps(const QByteArray &certificates,
                       const QByteArray &privateKey)
{
    const QList<QSslCertificate> certs = Utils::Net::loadSSLCertificate(certificates);
    const QSslKey key = Utils::SSLKey::load(privateKey);
    // Configuration applied to m_sslConfig
}

```

If loading succeeds, the server stores the resulting `QSslConfiguration` in `m_sslConfig`. All subsequent incoming connections are wrapped in `QSslSocket` instances created inside `Server::incomingConnection()`. The implementation further hardens security through `Server::safeCipherList()`, which filters out weak ciphers like *IDEA* or RSA-only key-exchange suites before the server advertises its cipher suite.

**Result:** All HTTP traffic to the Web UI—including API calls, JSON responses, and static assets—is encrypted with your provided certificate.

## Per-Torrent SSL Parameters

Individual torrents can maintain dedicated TLS configurations for encrypted peer connections through the `BitTorrent::SSLParameters` structure defined in [`src/base/bittorrent/sslparameters.h`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/sslparameters.h).

```cpp
// src/base/bittorrent/sslparameters.h
struct SSLParameters
{
    QSslCertificate certificate {};
    QSslKey          privateKey;
    QByteArray       dhParams;
    bool isValid() const;
};

```

### API Injection Point

When adding a torrent via the Web API, the `TorrentsController::addAction` method extracts SSL parameters from the request and constructs the `BitTorrent::SSLParameters` object:

```cpp
// src/webui/api/torrentscontroller.cpp
.sslParameters = {
    .certificate = QSslCertificate(params()[KEY_PROP_SSL_CERTIFICATE].toLatin1()),
    .privateKey  = Utils::SSLKey::load(params()[KEY_PROP_SSL_PRIVATEKEY].toLatin1()),
    .dhParams    = params()[KEY_PROP_SSL_DHPARAMS].toLatin1()
}

```

### Storage and Persistence

The parameters propagate through `SessionImpl::loadTorrentParams` and reside in `TorrentImpl::m_sslParams` inside [`src/base/bittorrent/torrentimpl.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/torrentimpl.cpp). During peer connection establishment, libtorrent reads these values to create TLS-encrypted sockets.

For persistence across restarts, `DBResumeDataStorage` serializes the certificate and key data into the SQLite resume database:

```cpp
// src/base/bittorrent/dbresumedatastorage.cpp
query.bindValue(DB_COLUMN_SSL_CERTIFICATE.placeholder,
               QString::fromLatin1(m_resumeData.sslParameters.certificate.toPem()));
query.bindValue(DB_COLUMN_SSL_PRIVATE_KEY.placeholder,
               QString::fromLatin1(m_resumeData.sslParameters.privateKey.toPem()));
query.bindValue(DB_COLUMN_SSL_DH_PARAMS.placeholder,
               m_resumeData.sslParameters.dhParams);

```

**Result:** Torrent-specific SSL configurations survive application restarts and are automatically reapplied to peer connections.

## Low-Level SSL Key Loading

Both Web UI HTTPS and torrent SSL parameters share the key detection logic in [`src/base/utils/sslkey.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/utils/sslkey.cpp). The `Utils::SSLKey::load()` helper automatically detects key type:

```cpp
// src/base/utils/sslkey.cpp
QSslKey Utils::SSLKey::load(const QByteArray &data)
{
    if (const QSslKey key{data, QSsl::Ec}; !key.isNull())
        return key;
    return {data, QSsl::Rsa};
}

```

This utility abstracts format detection, allowing qBittorrent to handle both EC and RSA private keys without manual user specification.

## Practical Configuration Examples

### Enable Web UI HTTPS via GUI

1. Open **Options → Web UI**
2. Check **Enable HTTPS**
3. Select PEM-encoded certificate and private key files
4. Restart qBittorrent
5. Access `https://127.0.0.1:8080`

### Add Torrent with SSL via HTTP API

Send a POST request to `/api/v2/torrents/add` with URL-encoded SSL parameters:

```http
POST /api/v2/torrents/add HTTP/1.1
Content-Type: application/x-www-form-urlencoded

urls=http://example.com/file.torrent&
ssl_certificate=%2F-----BEGIN%20CERTIFICATE-----%0A...%0A-----END%20CERTIFICATE-----%2F&
ssl_private_key=%2F-----BEGIN%20PRIVATE%20KEY-----%0A...%0A-----END%20PRIVATE%20KEY-----%2F&
ssl_dh_params=%2F-----BEGIN%20DH%20PARAMETERS-----%0A...%0A-----END%20DH%20PARAMETERS-----%2F

```

### Programmatic Key Loading

If handling raw PEM data in custom extensions:

```cpp
QByteArray pem = QFile::readAll("custom-key.pem");
QSslKey key = Utils::SSLKey::load(pem);
if (!key.isNull()) {
    // Key ready for QSslSocket or BitTorrent::SSLParameters
}

```

## Summary

- **Web UI HTTPS** is configured via `Http::Server::setupHttps()` in [`src/base/http/server.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/http/server.cpp), using `QSslConfiguration` with cipher suite filtering through `safeCipherList()`.
- **Per-torrent SSL** uses the `BitTorrent::SSLParameters` struct, injected via `TorrentsController::addAction` and stored in `TorrentImpl::m_sslParams`.
- **Persistence** is handled by `DBResumeDataStorage`, which writes certificate PEM data to SQLite columns `DB_COLUMN_SSL_CERTIFICATE`, `DB_COLUMN_SSL_PRIVATE_KEY`, and `DB_COLUMN_SSL_DH_PARAMS`.
- **Key loading** automatically handles EC and RSA formats through `Utils::SSLKey::load()` in [`src/base/utils/sslkey.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/utils/sslkey.cpp).

## Frequently Asked Questions

### Does qBittorrent support HTTPS for the Web UI?

Yes. Enable HTTPS in *Options → Web UI* and provide PEM-encoded certificate and private key files. The `Http::Server` class in [`src/base/http/server.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/http/server.cpp) implements this via `setupHttps()`, which configures `QSslSocket` for all incoming connections and filters weak ciphers through `safeCipherList()`.

### How do I add a torrent with SSL parameters via the API?

Send a POST request to `/api/v2/torrents/add` including `ssl_certificate`, `ssl_private_key`, and `ssl_dh_params` parameters containing PEM-encoded data. The `TorrentsController::addAction` method processes these into a `BitTorrent::SSLParameters` object, which libtorrent uses for encrypted peer connections.

### What SSL key formats does qBittorrent accept?

The `Utils::SSLKey::load()` function in [`src/base/utils/sslkey.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/utils/sslkey.cpp) automatically detects and handles both EC (Elliptic Curve) and RSA private keys. It attempts EC parsing first, falling back to RSA if necessary, eliminating the need for manual format specification.

### Are SSL parameters persisted across restarts?

Yes. Torrent-specific SSL configurations are serialized to the resume database by `DBResumeDataStorage` in [`src/base/bittorrent/dbresumedatastorage.cpp`](https://github.com/qbittorrent/qBittorrent/blob/main/src/base/bittorrent/dbresumedatastorage.cpp). The system stores certificate and key PEM data in dedicated SQLite columns, reloading them automatically when the application restarts.