How a Custom CA Certificate bricked my Android*

* at least a little bit.

One day, I decided to build my own Certificate Authority (CA) to enable HTTPS communication with applications in my home LAN. It wasn’t easy, but in the end, I successfully bricked my Android device.

Tl;DR: Here you can jump directly to the bricking part.

Basics

Click here to expand basics about CAs and HTTPS

Certificate Authorities (CAs)

Certificate Authorities (CAs) are trusted entities responsible for issuing digital certificates that verify the authenticity of websites, servers, or devices in secure communication. These certificates form the backbone of HTTPS, ensuring that data transferred over the internet remains private and secure. Many devices and browsers come preloaded with a set of trusted CAs.

HTTPS

HTTPS, short for Hypertext Transfer Protocol Secure, is an evolution of HTTP that ensures the connection between a user’s browser and the website server is encrypted. This encryption prevents third parties from intercepting sensitive information, such as passwords or financial data. HTTPS not only protects data integrity but also enhances user trust, as indicated by the padlock symbol in most browsers. It achieves this by using SSL/TLS protocols in conjunction with certificates issued by trusted CAs.

Why I Wanted My Own CA

Like many other IT professionals, I administrate several services that are just for me within my local network (LAN). These include a Pi-hole, a Home Assistant setup, a router, some Raspberry Pis, and a digital thermometer. Most of these devices and services are designed with simplicity and local usage in mind. They often rely on HTTP because, in controlled environments like home networks, the risks of external interference are minimal. This approach reduces complexity, eliminates the need for certificate management, and ensures ease of access for users who prioritize functionality over strict security measures. While this is sufficient for many scenarios, HTTPS becomes crucial when:

  • Transmitting sensitive data (e.g., credentials or API keys).
  • Integrating third-party apps that require secure communication.
  • Preventing potential eavesdropping, even in a local network.

In my case, I wanted to use the audio control features provided by Home Assistant. Commands like “Home Assistant, turn on the lights” or “Home Assistant, what’s the weather?” require microphone access, but modern browsers strictly prohibit microphone usage over insecure connections. Additionally, controlling sensitive systems like water flow or electricity through Home Assistant introduces significant risks, making security an essential consideration.

Creating Your Own Certificate Authority (CA)

While this is not the main focus of the article, here’s a concise guide:

# Create a private key
openssl genrsa -out my_local_ca.key 2048

# Create the public CA certificate
openssl req -x509 -new -nodes -key my_local_ca.key -sha256 -days 3650 -out my_local_ca.crt -subj "/CN=Your Local Root CA/O=Your Home/C=XX"

# Generate a certificate signing request (CSR) for your application
openssl req -new -nodes \
-keyout the-ha-key.pem \
-out the-ha.csr \
-config the-ha-openssl.cnf

# Use your custom CA to sign the CSR and create a certificate
openssl x509 -req \
-in the-ha.csr \
-CA my_local_ca.crt \
-CAkey my_local_ca.key \
-CAcreateserial \
-out the-ha.pem \
-days 730 \
-sha256 \
-extfile the-ha-openssl.cnf \
-extensions v3_req

# Verify the new certificate and check for included extensions
openssl x509 -in the-ha.pem -text -noout

Configuration File for OpenSSL

The process uses a configuration file with the following structure:

[ req ]
default_bits       = 4096
default_md         = sha256
prompt             = no
distinguished_name = req_distinguished_name
req_extensions     = v3_req
x509_extensions    = v3_req  # Extensions for x509 Certificates

[ req_distinguished_name ]
C  = DE
ST = Some State
L  = Some City
O  = Some Organization
OU = Some Unit
CN = myhomeassistant.local
emailAddress = your@mail.com

[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = myhomeassistant.local
IP.1  = your.ha.ip.address

I referenced this detailed guide and adjusted it for 2025.

Applying the Certificate to Home Assistant

To enable Home Assistant to use the certificate, add the following parameters to the configuration:

http:
  ssl_certificate: /ssl/the-ha.pem
  ssl_key: /ssl/the-ha-key.pem

Alternatively, install the Nginx add-on via the Home Assistant UI. I opted for Nginx, allowing me to run both HTTPS and HTTP simultaneously.

To this point, these were the sources I used:

Use your own CA file

Now that the web application uses HTTPS, all user devices and browsers must trust the certificate the application sends. This can be done easily by double-clicking to import it as a trusted root certificate on Windows or importing it via the Certificate Manager in Firefox. And just by that, https works seamlessly and I can use the microphone.

Use your own CA file - on Android

For reference, I tested this process on a Fairphone 4 with the non default operating System /e/OS from murena in Android version 13.

This is were it get’s tricky. At first you can follow this nice guide by The JeroenHD blog. Sidenote: The step “Tap the Firefox logo seven times” is a really obscure thing to do just to use an custom certificate. From here on, I was suspicious.

“You may need to restart the app.” After rebooting the device, it finally worked. I was able to establish a secure connection from my Android Firefox to the web application. However, this was just the beginning of the challenges. Strange issues started to arise, and I encountered multiple bugs simultaneously, making the resolution process chaotic and frustrating. Below, I’ve documented each bug, what it entailed, and how I eventually resolved it.

Bug 1: The HA-App

The official Android Home Assistant (HA) app stopped working. Naturally, I updated the URL to use HTTPS and port 443, but even then, a connection was not possible. I tried resetting the app, reinstalling it, but nothing worked. I always encountered a timeout.

A screenshot from the home assistant Android App containing an error message that occurred after I installed a custom CA on my Android device

The error persisted even after removing the custom CA from the system settings. (At that point, I genuinely feared the issue might be unresolvable.) After numerous attempts, what finally worked was:

  1. Starting the app.
  2. Rebooting Android while the app was open.
  3. After several tries, the app started working.

Bug 2: DAVx5

DAVx5, a popular app for syncing calendars and contacts, reported network I/O errors for all resources, including Nextcloud, Google Calendar, and holiday webcal providers.

A screenshot from the error messages of the Android App DAVx⁵ that occurred after I installed a custom CA on my Android device
I resolved this issue using the same method as in Bug 1.

Bug 3: The half f***g web

At this point, I was quite frustrated. Many websites failed to load, though not all of them. It made no difference weather I used the IP or an URL. I resolved this issue using the same method as in Bug 1, with the added step of frequently toggling Firefox’s setting to trust custom user CAs.

Bug 4: WLED

WLED is a popular open-source project for controlling LED lighting systems, often used in smart home setups. While the WLED app on my Android device successfully listed all WLED devices in the network, accessing the web interfaces of the light controllers was problematic (in the app as well as in the browsers. via ip or local dns). The interface would begin to load but then lose connection, resulting in a half-loaded, non-functional interface. Interestingly, the WLED API remained fully operational when accessed through Android device browsers, indicating the issue was specific to the web interface rendering.

A screenshot from the firefox browser attempting to connect to a WLED Device. Showing an Error that occurred after I installed a custom CA on my Android device

To rule out device-specific problems, I tested WLED functionality on other devices, and it worked flawlessly elsewhere. Unfortunately, this remains the only bug I couldn’t resolve despite extensive troubleshooting.

Bug n: every other App

It’s likely that almost any app could be affected by the implementation of a custom CA. Fortunately, I avoided testing additional apps. The potential for widespread compatibility issues remains.

Summary

I am now able to use the microphone on my PC browser with Home Assistant and for this I lost the ability to directly control my lights via my phone. Also this entire process likely cost me a few days of my life due to the stress it caused. I was able to resolve most bugs with many (many!) restarts and I hope by writing this into the net, someone is able to fix such problems faster.

The internet is full of descriptions of similar challenges, and to my knowledge, no one has yet found a definitive solution. Although Android is technically open source, Google exerts significant influence over its ecosystem. From the perspective of a company selling smart services, restricting the use of custom CAs is a reasonable measure - but I don’t like it.