Repository navigation
Security
Status: v0.12.3, not independently audited. Only standard JCA/JCE primitives are used (no custom cryptography, no third-party crypto libraries). Nobody outside the project has reviewed the design. Do not rely on it where lives or liberty depend on it.
The authoritative, always-current document is docs/SECURITY.md in the repository; this page is a summary.
| Property | How |
|---|---|
| Confidentiality between two nodes, even across relays | AES-256-GCM with a key only the endpoints can derive |
| Forward secrecy | ephemeral ECDH; keys live in memory only and are wiped when the session ends |
| Key rotation | new handshake after 1 hour or 500 messages, without interrupting traffic |
| Integrity and authenticity | GCM tag; sender, recipient, type, message ID and session ID are in the AAD |
| Delivery receipts cannot be forged | ACKs are sealed with the same session |
| HELLO cannot be forged or replayed | sealed, with an increasing sequence number |
| Relays cannot read or alter traffic | they hold no key for what they carry |
| A verified contact cannot be impersonated | its full key is pinned from the QR scan |
| Group messages | one pairwise-sealed copy per member, authenticated per author |
| At rest | text encrypted with an Android Keystore AES-256-GCM key; identity private key wrapped by it; allowBackup=false
|
- Each device has a P-256 key pair used for signing only; the node ID is the first 8 bytes of SHA-256(public key).
- Two
KEYpackets, a signed ephemeral Diffie-Hellman:-
A -> B:IA, EA, Sign_IA("req" | idA | idB | EA) -
B -> A:IB, EB, Sign_IB("resp" | idB | idA | EB | EA)
-
- Each side checks that the point is on the curve, that SHA-256 of the identity key matches the node ID, and the signature.
- Session keys:
HKDF-SHA256(ECDH(ea, EB))bound to both IDs and both ephemeral keys, expanded into one key per direction plus a 32-bit session id. Ephemeral private keys are dropped immediately. - The initiator adopts the session at once; the responder only after it decrypts a message under it, so a replayed request cannot hijack outgoing traffic. Retired sessions keep decrypting for two minutes; every session ends after two hours at most. Requests from one peer are accepted at most every 2 s, with at most 6 sessions per peer.
- Stopping the radio wipes every session key.
Scanning someone's QR code stores their key as verified and pins it in SessionManager. Verification is one-way. A code with a key not on the curve, or whose node ID collides with a different stored key, is refused.
Random 64-bit group ID, name (max 24 bytes), up to 8 members, one admin. No group key. The receiver enforces: invitations are pending until accepted; a message counts only if the group is joined and its authenticated sender is a member; only the admin can change name or members; a node left out of the admin's new list deletes the group.
- Forward secrecy is best effort on the device: the JVM may leave key copies in memory. It protects against later theft of stored keys, not a memory dump of a running app.
- Chat history is not forward secret: it is readable by anything that can use the Keystore key (an unlocked, compromised phone). Use CLEAR.
- Metadata is visible to anyone in Bluetooth range: node IDs and names (advertised), packet type, sender/recipient IDs, sizes, timing.
- Node IDs are 64 bits: impersonating a specific node needs about 2^64 work, out of reach for casual attackers but not a well-funded one. Verify in person for high-stakes use.
- First contact is trusted until you scan the contact's QR code.
- A stolen long-term key allows impersonation from then on (not decrypting the past). There is no revocation.
-
Denial of service (jamming, flooding) is not prevented.
DATA_REFUSEis unauthenticated and can be forged to stop a transfer. - Groups trust their admin and members: a removed member keeps what it received; a malicious member can send different texts to different members; no common ordering.
- Positions received are stored in clear in the app database; anyone who receives a position can keep and pass it on; the timestamp is the sender's clock.
-
Wi-Fi Direct: the group name
DIRECT-NW-xxxxis visible nearby and shows NodeWave is in use; an allowed peer can make your phone join and leave Wi-Fi networks. Photos have EXIF removed but pixels are sent. - A compromised phone exposes everything the app can read.
- Release builds are debug-signed for now; verify what you install.
Open an issue, or contact the maintainers privately for anything that looks exploitable.