Inspiration

I wanted to understand how much control people have over their privacy when they communicate online. Most messaging applications depend on infrastructure operated by a company, and many associate an account with a phone number. Encryption can protect message contents, but it does not automatically hide every piece of information surrounding a conversation.

This led me to explore whether two people could communicate directly without relying on a central messaging server. I started building Hermes around that idea, with a focus on applied cryptography, local identity management and network privacy.

The project also gave me an opportunity to work on systems programming beyond the usual application layer. I wanted to understand how cryptographic operations, network transport and a desktop interface could work together in a single application.

What it does

Hermes is an open-source desktop messenger built with Rust, React and Tauri. Its Rust engine, Aura, handles identity management, cryptographic operations, encrypted storage and Tor networking.

Users can create OpenPGP identities, sign messages, encrypt and decrypt files, and store their identities in a locally encrypted vault. The messaging system is designed to encrypt messages for the recipient and sign them with the sender’s key. On receipt, Hermes checks the signature against the contact’s pinned public key before displaying a message as verified.

For communication, Hermes embeds Arti, the Tor Project’s Rust implementation of Tor. Each installation can operate its own onion service, allowing peers to establish connections through Tor without a central Hermes server. The application also includes support for Tor bridges, which help users connect from networks that restrict access to Tor.

The project is designed to run across macOS, Windows and Linux from a shared codebase. Its broader goal is to give users more control over their identities and reduce the amount of information they must entrust to a third party.

How we built it

I worked on the application architecture, frontend, integration and Rust cryptographic engine. We built Hermes as a Tauri desktop application, with React providing the interface and Aura handling security-sensitive operations in Rust.

For OpenPGP functionality, we used Sequoia, alongside cryptographic components such as Ed25519 signatures and X25519 key agreement. The local vault uses Argon2id for passphrase-based key derivation and XChaCha20-Poly1305 for authenticated encryption. We also added measures to clear sensitive values from memory when they are no longer needed.

The networking layer uses Arti to run a Tor client and onion service within the application. For networks where direct Tor connections may be blocked, we integrated the lyrebird transport binary, which supports transports including obfs4 and Snowflake. The binary is downloaded at a pinned version and checked against its expected SHA-256 hash before being bundled.

We also separated the interface, Tauri command layer and Rust engine. This keeps the cryptographic implementation independent of the frontend and gives us a reusable engine that could eventually support other applications.

Challenges we ran into

One challenge was getting the different layers to work together without giving the interface unnecessary access to sensitive data. Although the cryptographic operations run in Rust, the current implementation still passes private-key material and passphrases through the frontend and command interface for some operations. Moving those secrets entirely into Rust is an important next step.

Networking introduced another set of challenges. Tor bridges need to work reliably, but obtaining bridge information can itself expose a user’s interest in Tor if the request bypasses Tor. Our testing confirmed that Hermes could bootstrap through public obfs4 bridges in 7.9 and 8.7 seconds on an Apple Silicon Mac. We still need to improve bridge discovery so that initial connections do not depend on an ordinary internet request.

Performance has also required careful attention. Cryptographic operations such as key generation and vault unlocking can block the interface because some commands currently execute synchronously. We’re working toward asynchronous operations and more efficient memory use, particularly for longer conversations.

We have also identified security limitations in the current design, including the absence of forward secrecy and replay protection. Documenting these issues has helped us establish a more specific development roadmap.

Accomplishments that we’re proud of

One of our main accomplishments is integrating identity management, OpenPGP operations, encrypted local storage and Tor networking into one desktop application.

We also built contact-key verification into the messaging flow. A message is not marked as verified simply because it contains a valid signature; the signing key must match the key pinned for that contact. Messages that fail decryption or verification are not displayed as verified.

Another milestone was getting Tor bridge connections working through the bundled transport on macOS, with the two measured bootstrap times recorded in our project documentation.

I’m particularly proud of the separation between Aura and the frontend. Working on the Rust engine, application architecture and integration gave me experience with the parts of a security-sensitive application that are easy to overlook when focusing only on its interface.

We have also documented the current implementation alongside its limitations. That gives us a concrete basis for deciding which security improvements need to happen before we make stronger claims about Hermes.

What we learned

Building Hermes taught me that secure communication involves more than choosing an encryption algorithm. A system also needs to verify identities, protect keys at rest and in memory, handle network metadata carefully and account for what happens when a device is compromised.

I also learned that privacy features can introduce their own engineering problems. Removing a central server reduces dependence on a service provider, but it means both peers generally need to be online at the same time. Tor can conceal network endpoints from peers, but requests that bypass Tor can still expose information about the user.

One of the most useful lessons was learning to distinguish a security property that has been implemented from one that exists only in the design. Hermes currently has several protections in place, but features such as forward secrecy, stronger replay protection and keeping private keys entirely inside Rust still require further work.

That distinction now informs how we document the project and prioritize its development.

What’s next for Hermes

Our immediate priorities are to keep private keys and passphrases inside the Rust engine, route or remove network requests that bypass Tor, and make cryptographic operations asynchronous so that the interface remains responsive.

We also plan to improve message handling with replay protection, stronger abuse controls and a versioned wire protocol. Forward secrecy is another major goal, likely requiring a ratcheting protocol built on top of the existing identity system.

Further work includes encrypted, opt-in chat history, better protection for onion-service identities, signed releases and automated security testing across supported platforms. Post-quantum key exchange using ML-KEM is also on the roadmap.

Hermes is an ongoing systems and security project. I want to continue developing it with an emphasis on testing, clear security boundaries and an honest account of what the implementation can protect against.

Built With

Share this project:

Updates

Submission history