dnscrypt
A high-assurance implementation of the DNSCrypt v2 client protocol. Built on an asynchronous, Tokio-backed API, this crate provides transport-level encryption and cryptographic authentication for all your DNS queries.
No unsafe code.
Features
- Audited Cryptography: X25519, Ed25519, constant-time comparison, and randomness are backed by
aws-lc-rs. The certificate's ES version selects betweenXChaCha20-Poly1305andXSalsa20-Poly1305(neither supported byaws-lc-rs), provided by the pure-Rustchacha20/salsa20/poly1305crates. - MITM Resistance: Relies on pinned resolver public keys hardcoded at compile-time to prevent CA-level compromise/spoofing.
- Robust TCP Fallback: Automatically and transparently retries queries over TCP if the decrypted DNSCrypt response indicates truncation (TC bit set).
- Reqwest Integration: Ships a drop-in
DnscryptResolverto route all host lookups in areqwest::Clientthrough DNSCrypt. - Async Tokio API: A single, focused async API — no synchronous entry points to keep in sync.
Feature Flags
| Feature | Description | Default |
|---|---|---|
reqwest |
Enables the DnscryptResolver for integration with reqwest::Client. |
Yes |
Cryptographic Specification
| Primitive | Protocol Role | Crate |
|---|---|---|
| X25519 DH | Per-session key agreement with the resolver | aws-lc-rs |
| HChaCha20 / HSalsa20 | Key derivation from the raw Diffie-Hellman secret | chacha20 / salsa20 |
| XChaCha20-Poly1305 / XSalsa20-Poly1305 | Authenticated encryption of queries/responses | chacha20 / salsa20 / poly1305 |
| Ed25519 | Resolver certificate signature verification | aws-lc-rs |
The AEAD construction used per-session is whichever ES version (0x0001 or 0x0002) the
resolver's certificate advertises — not a client-side choice.
Default Resolvers
HARDCODED_RESOLVERS ships 5 endpoints across 2 independently operated providers, each with its
Ed25519 provider public key pinned at compile time:
| Provider | Endpoints |
|---|---|
| Quad9 | 9.9.9.9:8443, 149.112.112.112:8443, 149.112.112.9:8443 |
| AdGuard DNS | 94.140.14.14:5443, 94.140.15.15:5443 |
Session establishment stops once it has 3 live sessions, so a typical run only contacts a subset of
these. Supply your own list via HardcodedResolver to bypass the
defaults entirely.
1. Simple Resolution
use ;
async
2. Reqwest Client Integration
Enable the reqwest feature flag to use DnscryptResolver:
use DnscryptResolver;
use Arc;
async
3. Custom DNSCrypt Resolvers
Bypass the default list of resolvers by supplying your own custom configurations:
use ;
use ;
const MY_RESOLVERS: & = &;
async
Security Hardening
This library has undergone systematic hardening to defend against transport-level threats:
- Randomized Padding & TXIDs: Queries are padded to randomized boundaries to prevent side-channel traffic analysis. Transaction IDs are derived from
aws-lc-rs's cryptographically secure random source. - Encrypted TC Detection: The parser decrypts responses before validating truncation. If a response is truncated inside the secure envelope, the resolver automatically executes a retry over TCP.
License
Licensed under the 0BSD license.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate shall be licensed as above, without any additional terms or conditions.