AES vs ChaCha20: Which Cipher Should You Use?
2026-10-14 · 6 min read
Figure 1: Two modern ciphers, two different strengths
The short version
AES and ChaCha20 are both excellent. Neither has a practical weakness, and you will find both in TLS, SSH and VPNs. If your code runs on a modern server or laptop, reach for AES. If it runs on older phones, small IoT boards or anything without a crypto chip, ChaCha20 is the better fit. The reason is hardware, not security.
Below is why that single factor decides most of it.
What AES is
AES is a block cipher. It works on fixed 16 byte chunks and uses a key of 128, 192 or 256 bits. Since 2001 it has been the default for governments, banks and browsers, and two decades of study have left its core untouched.
Its big advantage is silicon. Almost every current Intel, AMD and Apple chip ships with AES-NI, a set of instructions that run the cipher directly in hardware. That makes AES extremely quick and, just as important, resistant to timing side channels because the work no longer depends on secret-dependent table lookups.
On its own AES only scrambles data. To also detect tampering you pair it with a mode that authenticates, and the common pick is GCM. When people say AES-GCM, they mean the cipher plus that built-in integrity check.
What ChaCha20 is
ChaCha20 is a stream cipher designed by Daniel Bernstein. It takes a 256 bit key and produces a keystream that gets mixed with your data. For authentication it travels with Poly1305, so the usual name you will see is ChaCha20-Poly1305.
Where AES leans on special instructions, ChaCha20 was built to be fast using plain arithmetic that every processor already does well. It is constant time by design, so even without a crypto chip it stays quick and leaks nothing through timing. That is exactly why Google pushed it for mobile: on a phone lacking AES-NI, ChaCha20 often beats a software version of AES by a wide margin.
You can experiment with both in the browser using the AES tool and the ChaCha20-Poly1305 tool.
Side by side
| Point | AES-GCM | ChaCha20-Poly1305 |
|---|---|---|
| Type | Block cipher | Stream cipher |
| Key size | 128 / 192 / 256 bit | 256 bit |
| Speed with crypto hardware | Excellent | Very good |
| Speed without crypto hardware | Slower, can leak timing | Excellent, constant time |
| Best home | Servers, desktops | Phones, IoT, embedded |
| Authentication partner | GCM | Poly1305 |
Where each one shines
A web server behind a CPU with AES-NI will push more traffic with AES-GCM than anything else, so that is the sensible default for backend work. TLS 1.3 agrees: it keeps AES-GCM at the top of the list for hardware that supports it.
Move to a budget Android handset, a router or a microcontroller and the picture flips. Those parts rarely carry AES acceleration, so a software build of AES crawls and can expose timing hints. ChaCha20 sidesteps both problems, which is why WireGuard chose it and why TLS 1.3 clients without acceleration quietly switch to it.
The rule that applies to both
Whichever you choose, never reuse a nonce with the same key. A nonce is the small value that keeps each message unique. Repeat one under GCM or Poly1305 and the authentication collapses, which can expose the key stream and let an attacker forge messages. Generate it from a secure random source every time, or use a counter you are certain will never wrap.
So which do you pick?
- Running on normal server or desktop hardware? Use AES-GCM.
- Targeting mobile, IoT or anything without a crypto chip? Use ChaCha20-Poly1305.
- Writing something that must run everywhere and stay simple? ChaCha20 is the safer default, since it performs well on every device and is harder to misuse in software.
Both will protect your data for the foreseeable future. The decision is really about the machine, not the math, so let the hardware guide you and move on to the parts of your system that are genuinely harder to get right.