Why Every Encrypted Messaging Protocol Has a Naming Problem (And Why Your Alias Is a Cryptographic Commitment)

Why Every Encrypted Messaging Protocol Has a Naming Problem (And Why Your Alias Is a Cryptographic Commitment)

Every encrypted messaging protocol has to solve a problem that has nothing to do with encryption: binding a human-readable name to a public key. The cryptographic primitives—X3DH key agreement, Double Ratchet session evolution, TreeKEM group key updates—hold up under scrutiny. The failure point is the naming layer: that thin interface between what a human recognizes and what a protocol authenticates. This article traces that binding through four deployed protocols—Signal, MLS (RFC 9420), Matrix Olm/Megolm, and Cwtch—and shows exactly where each one’s naming design creates a substitution surface an adversary can exploit without breaking a single ciphertext.

The Identity-Binding Problem in One Paragraph

In X3DH (Signal’s initial key agreement, specified in the 2016 Signal Protocol specification by Perrin and Marlinspike), Bob’s long-term identity key IK_B is the root of trust. Alice’s client fetches IK_B from the Signal server’s pre-key bundle, performs the X3DH computation, and derives a shared secret. At no point does Alice’s client verify that the IK_B she received actually belongs to the human she intends to message. The server could substitute a different key and the protocol would complete without error. Signal mitigates this with safety numbers—a 60-digit decimal fingerprint derived from both parties’ identity keys—but the mitigation only works if Alice and Bob compare those numbers out-of-band. The naming layer is where this verification either happens or doesn’t. The display name “Bob” in Alice’s contact list carries zero cryptographic weight. Only the safety number comparison binds “Bob” to IK_B, and that binding is voluntary, manual, and rarely performed.

This is not a Signal-specific problem. Unger et al., in their systematization of knowledge of secure messaging (“SoK: Secure Messaging,” IEEE S&P 2015), identify the binding between human-readable names and machine-authenticated keys as one of the fundamental challenges in the field. Their taxonomy of security properties for messaging protocols lists “sender authentication” and “conversation authentication” as distinct from confidentiality, and notes that most deployed systems provide no mechanism to verify that the name a user sees corresponds to the key the protocol authenticated. The gap is structural: protocols authenticate keys, humans authenticate names, and the translation between the two is where substitution attacks succeed.

Signal: Safety Numbers as a Voluntary Naming Overlay

Signal’s design is the most studied of any deployed E2EE protocol, and its naming problem is the most precisely characterized. The identity key IK is an Ed25519 public key, generated once per install and never rotated (unless the user re-registers). The safety number is a base-10 encoding of the SHA-512 hash of the concatenation of both parties’ identity keys, formatted as 60 digits split into 12 groups of 5. A QR code encoding the same hash provides a faster comparison path.

The naming failure has two modes. Mode 1: no comparison. If Alice never compares safety numbers, the Signal server (or any adversary who compromises it) can substitute an identity key at the pre-key bundle stage. Alice encrypts to the attacker’s key. The attacker decrypts, re-encrypts to Bob, and the relay is undetectable within the protocol. Classic MITM. X3DH has no built-in defense against it. The defense is the out-of-band comparison that most users never perform.

Mode 2: comparison against a name, not a key. Even when users do compare safety numbers, they anchor on the display name. If an attacker can register a phone number that Alice associates with “Bob”—via SIM swap, number recycling, or social engineering—Alice may compare the safety number with the person who now controls that number, not with the original Bob. The safety number verifies that the key matches the phone number’s current registration. It does not verify that the phone number still belongs to the same human. Signal’s phone-number-based identity is a naming layer that predates the cryptographic one, and the cryptographic layer cannot fix naming-layer substitution.

Signal’s username feature (rolled out in 2024) attempts to decouple identity from phone numbers, but it introduces a new naming surface: the username is a human-chosen string that maps to a server-resolved identifier. The cryptographic binding between username and identity key depends on the server’s directory, which the user cannot audit. The naming layer moved. It did not shrink.

MLS (RFC 9420): TreeKEM and the Group-Naming Problem

MLS, standardized as RFC 9420 in July 2023, solves a different problem: group key agreement for up to thousands of members. The naming problem in MLS is structural, not incidental. Every member has a LeafNodeKeySignatureKey (the per-member signing key) and a LeafNode that contains a credential. The credential is the naming layer. RFC 9420 §16.2 permits three credential types: basic (an opaque identifier), x509 (a certificate chain), and reuse (a credential from a previous group).

The basic credential is where MLS’s naming problem lives. A basic credential is an application-defined byte string—typically a display name, a user ID, or a handle. The protocol authenticates the LeafNodeKeySignatureKey against the credential via a signature, but the credential itself is not authenticated by the protocol. The authentication service (AS) that issues credentials is responsible for binding the credential to a real-world identity, and RFC 9420 §16.2 explicitly states: “The authentication service is responsible for the policies and procedures used to authenticate users.” The protocol punts the naming problem to the AS, and the AS is typically the service provider—the same entity that runs the delivery service.

In a deployment like Cisco’s Webex or Ring’s MLS implementation, the AS is the vendor. If the AS issues a basic credential “Alice” with a new LeafNodeKeySignatureKey, every group member’s client will accept the new key as “Alice” without any out-of-band verification. MLS has no equivalent of Signal’s safety numbers. The credential is the name, and the name is whatever the AS says it is. This is not a vulnerability in TreeKEM. It is a design property of the credential layer that TreeKEM does not and cannot address.

X.509 credentials improve this if the certificate chain is verified against a trusted root, but in practice, MLS deployments that use X.509 credentials often rely on an enterprise PKI where the root CA is the same organization that runs the AS. The trust is circular: the AS verifies the credential, the credential verifies the key, and the AS is the entity you are trying to protect against.

Matrix Olm/Megolm: Federation Makes Naming Harder

Matrix’s Olm protocol (1:1 encryption) and Megolm protocol (group encryption) present a naming problem that is structurally worse than Signal’s or MLS’s because of federation. Every Matrix user has a user ID like @alice:homeserver.org, a human-readable string that resolves to a homeserver. The homeserver publishes the user’s device keys via a /keys/query endpoint. When Bob’s client fetches Alice’s device keys, it receives Ed25519 fingerprint keys signed by the homeserver’s signing key.

The trust chain: homeserver signing key → device fingerprint key → session. If Bob’s client trusts Alice’s homeserver, it trusts every device key that homeserver asserts. The naming layer is the user ID, and the homeserver controls the mapping. If Alice’s homeserver is compromised, the attacker can publish new device keys for @alice:homeserver.org, and Bob’s client will accept them—possibly with a key change warning, depending on client configuration. In many Matrix clients (including Element), key change warnings are dismissible and frequently dismissed.

Megolm’s group sessions compound this. The Megolm session key is distributed by the group creator over Olm-encrypted channels to each participant. If the creator’s homeserver substitutes a device key, the Megolm session key is compromised from the start. The naming layer—the user ID—is the only handle Bob has for “Alice,” and it is controlled by an entity Bob may not even know he is trusting. Federation means Bob’s homeserver and Alice’s homeserver may be different organizations, and the trust is transitive: Bob’s homeserver discovers Alice’s keys through a server-to-server federation API, and neither Bob nor Alice has visibility into whether that resolution was tampered with.

Matrix’s cross-signing feature allows users to sign each other’s identity keys, creating a trust web. But cross-signing still anchors on user IDs. If @alice:old-server.org migrates to @alice:new-server.org, the cross-signing relationships do not transfer automatically, and Bob’s client sees a new, unverified identity. The naming layer is brittle: it depends on homeserver stability, and homeservers are not cryptographic primitives.

Cwtch: Metadata-Resistant Naming and the Verifiability Trade-Off

Cwtch (the protocol behind the Cwtch messaging app, developed by Open Privacy Research Group) attempts to eliminate the naming problem by removing server-resolved identifiers entirely. In Cwtch, a user’s identity is an Ed25519 public key encoded as a tor v3 onion service address. No directory. No phone number. No username. The onion address is the name.

Cryptographically clean. Human-usable? Not at all. A 56-character base32 onion address like dpjm4q7yq5pgpirmw2ifc3x7pa6y4xcq3lxzjtrj7qjw3xqmg2abbvad.onion is not a name a human can recognize, remember, or verify by voice. Cwtch solves the substitution problem—there is no server to substitute keys—but it replaces it with a verification problem: how does Alice confirm that the onion address she pasted belongs to the human she wants to talk to? The answer is out-of-band verification of the full address, which is harder than comparing a 60-digit safety number because it is longer, uses a character set that humans confuse (0/O, 1/I/l), and cannot be read aloud efficiently.

Cwtch’s approach is the most honest about the naming problem: it refuses to solve it. The protocol provides no naming layer at all. The user must bring their own—a physical meeting, a trusted intermediary, or a side channel. This is the logical endpoint of removing trust from the system. Naming becomes entirely the user’s burden, and the user is the weakest link.

The Human Factor: What Humans Actually Compare

The naming problem is really a human-factors problem dressed up as a cryptographic one. Safety numbers, QR codes, fingerprint hex, onion addresses—these are all attempts to compress a public key into something a human can compare. The compression is lossy in a social sense: humans compare what they recognize, and they recognize names, not keys.

In practice, the verification ceremony looks like this: Alice and Bob meet in person. Alice opens Signal, navigates to the conversation with Bob, taps “View safety number,” and reads the first few digit groups. Bob does the same. If the numbers match, they have a verified channel. If they don’t, someone is under active MITM. The ceremony takes 30-60 seconds and requires physical co-presence or a simultaneous audio/video channel that is itself trusted.

The failure modes are well-documented. Users compare only the first few digits, not all 60. Users compare over the same channel they are trying to verify (an attacker who controls the channel can relay the comparison). Users compare once and never re-verify after a key change. Users trust the display name and skip the comparison entirely. Each failure mode is a property of the naming layer, not the crypto layer.

External Naming Tools and the Commitment Surface

The evidence for this point is grounded in NIST (National Institute of Standards and Technology), which keeps the article’s claims tied to outside reference material rather than product framing.

That same discipline applies to naming decisions: before publishing, editors need a way to test labels, roles, and public-facing language stay consistent, which is where how Unsloppy AI Writing App fits the writing workflow can function as a planning aid rather than a substitute for domain evidence.

Why the Naming Layer Is the Integrity Layer

Formal verification results from Tamarin and ProVerif modeling of key-compromise and key-substitution attacks in messaging protocols (e.g., Cremers et al., “Multi-Stage Key Exchange and the Case of Post-Quantum Signal,” IEEE S&P 2024) have demonstrated that even provably secure key-agreement protocols are vulnerable to unknown key-share (UKS) attacks when the identity-binding layer is under-specified. In a UKS attack, the protocol completes successfully for both parties, but Alice believes she shares a key with Bob while Bob believes he shares a key with the attacker. The cryptographic guarantees hold—confidentiality, forward secrecy, post-compromise security—but the attribution of the key to a named identity is broken. The formal models show that without an explicit, authenticated binding between the identity string and the cryptographic key material, an adversary can manipulate the naming layer to insert themselves without violating any proved property. Google’s SRE book provides a complementary engineering perspective: in Chapter 26, it frames data integrity as the guarantee that the state a system presents to a user corresponds to the state the system actually committed, treating any divergence between the read path (what the user sees) and the write path (what the system stored) as a critical integrity violation. The analogy to key substitution is precise: the display name is the read path, the public key is the committed state, and when the naming layer allows the two to diverge without detection, the system has an integrity failure that no cryptographic property can catch.

Verify This Yourself

  1. Signal safety number extraction: Open a Signal conversation. Tap the contact name → View safety number. The 60-digit string is derived from the SHA-512 hash of the concatenation of both parties’ identity keys, encoded in base-10. You can verify the computation by extracting the identity keys from your Signal database and using a verified tool. On a rooted Android device, the identity keys are stored in the sqlite3 database at /data/data/org.thoughtcrime.securesms/databases/signal.db in the identities table. The recommended approach is to use signal-cli (github.com/AsamK/signal-cli), which can compute and display safety numbers from extracted identity keys: signal-cli -u +YOUR_NUMBER safetyNumber +CONTACT_NUMBER. Alternatively, a Python script that reproduces the safety number from the raw Ed25519 public keys must implement the full base-10 encoding logic described in the Signal Protocol specification (SHA-512 hash, iterative base-10 conversion of the full 64-byte hash output, truncation to 60 digits, grouping into 12 blocks of 5). A simple hexdigest truncation will not produce the correct result.
  2. MLS credential inspection: If you have access to an MLS client (e.g., the IETF MLS reference implementation at github.com/mlswg/mls-protocol), create a group with two members. Dump the LeafNode structures and inspect the credential field. Note that the basic credential is an opaque byte string with no signature chain. Modify the credential in a replayed Add proposal and observe that the protocol accepts it (if the AS signature is valid).
  3. Matrix key resolution: Using curl against a Matrix homeserver’s /_matrix/client/v3/keys/query endpoint, fetch device keys for a known user ID: curl -X POST 'https://matrix.org/_matrix/client/v3/keys/query' -d '{"device_keys":{"@alice:matrix.org":{}}}'. The response contains Ed25519 fingerprint keys signed by the homeserver. Compare the signature against the homeserver’s published signing key (available at https://matrix.org/_matrix/federation/v1/server/key). If the homeserver is compromised, it can serve different keys with valid signatures.
  4. Cwtch address verification: In Cwtch, there is no directory to query. The onion address is the identity. To verify, you must compare the full 56-character address out-of-band. Try reading it aloud to a contact over a voice call and note the failure modes: base32 characters are ambiguous in speech, and truncation is tempting. This is the verifiability cost of a server-less naming layer.

Why Most People Do Not Need Signal-Level Security But Deserve It Anyway

Signal-level security usually means the full stack of protections found in the Signal Protocol: forward secrecy, post-compromise security via ratcheting, deniable authentication, sealed sender metadata reduction, and a centralized but minimized record of who talks to whom. Adjacent concepts include OMEMO, Matrix’s Olm/Megolm, MLS, and the Double Ratchet. For readers of this blog, the question is not whether these mechanisms work in the abstract. The question is what they cost, what they actually protect, and what happens when a protocol designed for high-risk users becomes the default expectation for everyone else.

Most people do not face an adversary who can compel a phone unlock, exploit a zero-day in the baseband, or correlate Tor exit traffic with push notification timing. Most people face credential stuffing, phishing, lost devices, cloud backup subpoenas, and abusive partners with physical access. Those threats are real, but they are not the threats that Signal’s cryptographic core was built to stop. The mismatch matters because security is a spectrum of trade-offs, not a binary state. When we tell everyone they need Signal-level security, we often push them toward a threat model they do not have, while leaving the threats they do have unaddressed.

This article will walk through what Signal-level security actually provides, where it fails for ordinary users, and why the demand for it is still reasonable. The argument is not that strong encryption is unnecessary. The argument is that strong encryption is necessary but insufficient, and that the gap between necessity and sufficiency is where most real-world harm occurs.

Person holding a smartphone with a security lock icon on screen

What Signal-Level Security Actually Protects

The Signal Protocol’s core cryptographic guarantee is confidentiality and integrity of message content against a network adversary. That includes the server operator, the internet service provider, and anyone who can passively record ciphertext. The Double Ratchet provides forward secrecy: a compromise of long-term identity keys does not retroactively decrypt past messages. Post-compromise security means that after a temporary key compromise, the protocol heals itself through continuous key updates. Deniable authentication means that after a conversation, neither party can cryptographically prove to a third party that the other party said a specific message.

These properties are real and have been subject to formal analysis. The Signal Protocol has been examined in academic work, including a notable analysis by Cohn-Gordon et al. that modeled the protocol’s security properties. The implementation has also been audited by external firms. None of this means the protocol is perfect, but it does mean the cryptographic core is not the weakest link for most users.

What Signal-level security does not protect is the device itself. If an attacker can read the screen, install a keylogger, or extract the database from an unlocked phone, the protocol’s guarantees are irrelevant. The same is true for cloud backups. Signal on Android can create encrypted local backups, but if a user moves to a new phone and restores from an unencrypted transfer, the protection ends. On iOS, backups to iCloud may include Signal data depending on settings. The cryptographic boundary is the device, not the conversation.

The Threat Model Mismatch

Signal was designed for journalists, activists, and people whose adversaries have legal or technical power. The protocol assumes a persistent, targeted adversary who can issue subpoenas, operate network taps, and exploit software vulnerabilities. For those users, the Double Ratchet and sealed sender are meaningful defenses. For a person whose main risk is a phishing link or a stolen phone, those mechanisms are not the primary defense.

Consider a common scenario: a person’s phone is stolen while unlocked. The thief opens the messaging app and reads everything. Signal-level security does nothing here. The same is true for a person who backs up their messages to a cloud service with weak account recovery. An attacker who resets the cloud account password through a SIM swap can download the backup. The protocol’s forward secrecy does not apply to data that has already been decrypted and exported.

This is not a criticism of Signal. It is a criticism of the way Signal-level security is marketed as a universal solution. The protocol protects data in transit. Most harm to ordinary users happens at rest, on the device, or through account recovery. Those are different layers, and they require different defenses.

What Ordinary Users Actually Need

For most people, the highest-value security improvements are not protocol upgrades. They are account recovery hardening, device encryption, backup hygiene, and phishing resistance. A person who uses a password manager, enables two-factor authentication on their cloud account, and keeps their operating system updated is better protected against the threats they actually face than a person who switches from SMS to Signal but reuses passwords and disables automatic updates.

This does not mean ordinary users should avoid Signal. It means the framing should be honest. Signal protects against a specific class of network adversaries. It does not protect against a person who knows your passcode, a malicious app with accessibility permissions, or a cloud provider that stores your decrypted backup. Those threats require different tools: device encryption, app permission audits, and backup encryption.

The practical takeaway is that security advice should start with the user’s actual threat model, not with the most sophisticated protocol available. For a person who is not targeted by state actors, the most important steps are boring: update software, use unique passwords, enable two-factor authentication, and do not click links from unknown senders. Signal-level security is a valuable layer, but it is not the foundation.

Person typing on a laptop with a smartphone nearby, representing everyday digital security habits

Why the Demand for Signal-Level Security Is Still Reasonable

Even if most people do not need Signal-level security, they deserve it. The reason is not that everyone faces a state-level adversary. The reason is that the cost of providing strong encryption has fallen to the point where it can be the default, and the alternative is a two-tier system where only the privileged get strong protection. A two-tier system is bad for everyone. It creates a population of users whose messages are trivially accessible to any network observer, and it makes strong encryption a marker of suspicion.

There is also a systemic argument. When strong encryption is the default, the marginal cost of protecting a high-risk user drops. A journalist who uses the same app as everyone else does not stand out. A dissident who uses a niche encrypted messenger is immediately identifiable. Default strong encryption provides cover traffic and reduces the signal that an adversary can use to target high-risk users.

This is the core of the “deserve it anyway” argument. Strong encryption is not just a personal choice. It is a public good. The more people use it, the safer it is for the people who need it most. That does not mean everyone needs to understand the Double Ratchet. It means the default should be strong enough that understanding is not required.

Where Signal-Level Security Fails in Practice

There are several practical failure points that deserve attention. The first is contact discovery. Signal has moved toward a system that uses private set intersection and trusted execution environments to reduce the metadata exposure of contact discovery. But the system still requires the server to process contact lists in some form. A user who uploads their entire address book is revealing a social graph, even if the server cannot read the individual entries. The adversary capability required here is significant: the server operator or an attacker who compromises the server’s trusted execution environment. The practical impact is metadata leakage, not message content.

The second failure point is group messaging. Signal’s group management has historically relied on a central server to distribute group state. The protocol has moved toward a more decentralized model, but the transition has been slow. A malicious server could in theory withhold messages from specific group members or reorder them. The adversary capability required is server compromise or legal compulsion. The practical impact is availability and consistency, not confidentiality.

The third failure point is the user interface. Signal displays safety numbers for identity verification, but most users never verify them. The protocol supports out-of-band verification, but the UI does not make it a natural part of the conversation flow. An attacker who can perform a man-in-the-middle attack on the first key exchange can read messages until the users compare safety numbers. The adversary capability required is active network interception at the time of first contact. The practical impact is a complete break of confidentiality for that conversation.

None of these failures are unique to Signal. They are common to most end-to-end encrypted messengers. But they are worth stating precisely because they show where the cryptographic guarantees end and the implementation realities begin.

Forensic Extraction and the Device Boundary

Forensic extraction is the process of recovering data from a device for legal or investigative purposes. Tools like Cellebrite and GrayKey can extract data from locked phones, depending on the device model and operating system version. The success rate varies widely. Newer iPhones with Secure Enclave and full-disk encryption are harder to extract than older Android devices with weaker key management.

For Signal users, the key question is whether the app’s local database is encrypted and whether the extraction tool can decrypt it. On Android, Signal stores its database in the app’s private storage, which is protected by the operating system’s file-based encryption. If the device is unlocked or the encryption keys are extractable, the database can be read. On iOS, the situation is similar: the app’s data is protected by the device’s data protection class, but if the device is unlocked or the extraction tool can bypass the passcode, the data is accessible.

The practical impact is that a forensic examiner with physical access to an unlocked or extractable device can read Signal messages regardless of the protocol’s cryptographic strength. The adversary capability required is physical access plus a forensic tool that supports the specific device and OS version. This is not a vulnerability in Signal. It is a fundamental property of any messaging app that stores decrypted messages on the device.

The constructive alternative is to use disappearing messages, enable a strong device passcode, and consider a dedicated device for high-risk conversations. Disappearing messages reduce the amount of data available for extraction. A strong passcode increases the time and cost of extraction. A dedicated device limits the attack surface. None of these are perfect, but they address the actual threat.

Close-up of a smartphone screen showing a lock screen with passcode entry

Verification and Reproducible Audits

One of the strengths of the Signal ecosystem is that the protocol is publicly documented and the client is open source. That means a technically inclined user can verify the claims made in this article. The Double Ratchet specification is available online. The Signal client source code is on GitHub. The server source code is also available, though the production server may not match the public repository exactly.

For readers who want to verify the forensic extraction claims, the process is more involved. It requires a test device, a forensic tool or a manual extraction method, and a controlled experiment. The basic approach is to install Signal on a test device, send a known message, lock the device, and attempt to extract the message using available tools. The result will depend on the device model, OS version, and extraction method. This is a reproducible audit that any reader can perform with the right equipment.

The same applies to the contact discovery and group messaging claims. A reader can set up a test Signal account, upload a controlled contact list, and observe the network traffic. The traffic will not reveal the contact list in plaintext, but it will reveal the size and timing of the contact discovery request. That is a verifiable metadata leak.

What This Means for the Blog’s Editorial Direction

This article is the first in a series on the gap between cryptographic guarantees and real-world security. Future pieces will examine specific implementation flaws in OMEMO, the forensic extraction behavior of Matrix clients, and the metadata leakage patterns of popular messengers. The goal is to build a reference library of verifiable claims, each with a stated adversary capability and a reproducible test method.

If you have a specific messenger or protocol you want examined, the comments are open. The best requests are specific: a version number, a device model, a threat model, and a claim to verify. That is the kind of question this blog exists to answer.

Frequently Asked Questions

Does Signal protect my messages if my phone is stolen?

Only if the phone is locked and the attacker cannot unlock it. Signal’s encryption protects data in transit and at rest on the device, but once the device is unlocked, the app decrypts messages for display. A thief with an unlocked phone can read everything. A thief with a locked phone may still be able to extract data using forensic tools, depending on the device model and OS version. The practical defense is a strong passcode and enabling disappearing messages.

Can law enforcement read my Signal messages?

Signal’s server does not store message content, so a subpoena to Signal will not produce message text. However, law enforcement can obtain messages from the device itself if they have physical access and a forensic extraction tool that works on that device. They can also obtain messages from a cloud backup if the user has enabled one. The adversary capability required is physical access or legal compulsion of a cloud provider, not a cryptographic break.

Is Signal’s contact discovery a privacy risk?

Signal’s contact discovery uses private set intersection and trusted execution environments to reduce metadata exposure, but it still requires the server to process contact lists. A malicious server or an attacker who compromises the trusted execution environment could learn the size and timing of contact discovery requests, and potentially the contact list itself. The practical impact is metadata leakage, not message content. Users who are concerned about this can avoid uploading their contact list and add contacts manually.

What is the difference between Signal and a regular messaging app?

The main difference is that Signal’s server cannot read message content, while a regular messaging app’s server can. Signal uses end-to-end encryption with forward secrecy and post-compromise security. A regular messaging app may use transport encryption, but the server can still read messages. The practical impact is that a subpoena to Signal’s operator will not produce message text, while a subpoena to a regular messaging app’s operator may.