Presenting DNSDH

DNSDH is a protocol for exchanging cryptographic keys using the Diffie-Hellman algorithm. Instead of exchanging keys traditionally, the clients speak to a bogus DNS server to initiate an encrypted session in an existing channel of communication. The cryptographically relevant packets travel through a data path that appear to be normal domain name resolve queries to remain stealth and effective even behind limited and surveillanced networks. Please understand that the DNS server is only pretending to be a server for performing name lookups by using its language but performing different tasks.

The bogus DNS server is the center of the key exchange. It uses memcached to store data in memory and deletes any output after it’s been delivered to its recipient. The point of DNSDH is to establish a reliable network enabling anything that can perform a DNS request to exchange cryptographic keys using discrete bogus domain name queries. The nodes communicating, Alice and Bob, could possibly be two cellphones, IRC clients or even death stars. It’s also a great blast to teasingly merge cryptographic key exchanges with traffic that is rarely looked at by network administrators unless they want to censor or monitor you.

When initializing the session Alice first declares the values of p, g and Alice’s private key (alice_private) and then queries the bogus DNS server with dnsdhinit.p.g.alice_public. The DNS server creates a sessionid and stores it in the memory with the data provided in Alice’s query. Alice tells Bob that she wants to talk privately and sends him a packet containing the sessionid provided by the DNS server. Bob queries the DNS server with the sessionid recieved from Alice. The DNS server replies with the information provided in Alice’s query. Bob then proceeds by declaring his own private key (bob_private) and calculates the value of his public key: g^bob_private mod p. Bob can then calculate the secret he shares with Alice: alice_public^bob_private mod p. Then Bob queries the DNS server with dnsdhinit.bob_public, receives an id and sends it to Alice in a packet. Alice then queries the DNS server with the id, receives bob_public and calculates the secret she shares with Alice: bob_public^alice_secret mod p.


$ ./ 1337 1338 init
[+] Generating keys...
[+] alice_pub_key: 7
[+] alice_priv_key: 19
[+] Query dnsdhinit.23.5.7
[+] SEND DNSDH_INIT: 6035559
[]: DNSDH_FINISH: 9300804
[+] Query sessionid.9300804
[+] p: 23
[+] g: 5
[+] bob_public: 1
[+] Shared secret: 1


$ ./ 1338 1337
[]: DNSDH_INIT: 6035559
[+] Query sessionid.6035559
[+] p: 23
[+] g: 5
[+] alice_public: 7
[+] Generating keys...
[+] bob_pub_key: 1
[+] bob_priv_key: 0
[+] Shared secret: 1
[+] Query dnsdhinit.1
[+] SEND DNSDH_FINISH: 9300804

Source code

The source code is available on Github.

6 Responses to “Presenting DNSDH”

  1. Per Says:

    Why are you using Diffie-Hellman and not rolling your own cryptographic algorithm?

  2. Niklas Femerstrand Says:


    Diffie-Hellman is an algorithm that handles only the exchange of cryptographic keys, it is not a cryptographic algorithm. Diffie-Hellman is just a way of ensuring that the crypto keys are transferred securely before used as the key by a cryptographic algorithm, like AES, Twofish, etc.

    DH hasn’t been proven to be insecure and is used more or less as a standard anonymous key agreement and to provide perfect forward secrecy. Even though I’ve been experimenting with my own key exchange techniques for quite a few years I don’t feel ready publishing anything related to those when publishing more solid stuff.

    In the end of the day it’s really hard for my toy box key exchange algorithms to compete with something that’s been around for over 35 years and still goes strong in software like SSL, SSH and IPSec.

    I’m still experimenting with other key exchange methods but I don’t want the insecurities of them to pull other projects down in eventual downfalls. I’m still playing with them though, and if I ever come up with something I’m comfortable publishing then I definitely will.

    Ironically enough the dnsdh daemon can be used to transmit more or less any data between two nodes communicating with each other and the dnsdh deamon. It’s really not DH specific at all, unless the clients decide it to be.

  3. agtrier Says:

    This sounds like an interesting hack. What I struggle to understand is what is the real advantage of this over a simple direct exchange between Alice and Bob?

  4. qnrq Says:


    My goal is to make the dnsdhd redundant and decentralized, possibly by using some sort of BitTorrent like distribution hash table. Or just straight up piggyback ride on it directly. I haven’t read the BitTorrent RFCs so I’m not sure yet, but I’m curious to find out if I could use magnetic URIs as data storage in “the cloud”.

    There is no direct exchange between Alice and Bob unless they physically meet and exchange data. There’s always a transport client or server, in the case of IRC daemons they could very easily be modified to routinely conduct MITM attacks against users relying on FiSH crypto plugins. I want to anonymize the crypto key exchange so that it can be relied on even in extreme circumstances.

    The current release of DNSDH isn’t secure and shouldn’t be used for anything else than demonstration though. It’s still lacking some sort of message authentication between node and DNS server.

    This is a very early demonstrative alpha just to show that DH can in fact take the DNS path (quite easily, too). When life gives you data retention laws, make stealth crypto software and piss life off.

  5. Michael Says:

    I think this might be a typo: “…queries the bogus DNS server with dnsdhinit.p.g.alice_private”. Should be alice_public, right?

  6. qnrq Says:


    Fixed the typo, thanks a lot!

Leave a Reply

Leave a Reply

Your email address will not be published.