Archive for September, 2014

Web-of-Trust DNS

Originally published here, copied below (edits and references coming later):

Previously mentioned on my blog here:

WoT-DNS – Description


TL;DR: A system for deciding where domain names should go based on who you trust.

WoT-DNS is my proposal for a new P2P based DNS system.

This system decides where a domain name like reddit.wot should go based on your trust, as an invidividual; it does not care about the opinion of random strangers. You are the one who choose who’s trusted and who’s not, since it’s using WoT (web of trust). Also, domain names are intentionally NOT globally unique, since the only way to achieve that is with a centralized service or a first-come, first-serve system like Namecoin, and I dislike both those solutions. This means that if you would ask for a sitename like reddit.wot, you could get many results instead of going straight to one site. But whenever one site is trusted (for you) much more than the rest (like reddit’s official site would be), that’s where you’ll go.

Basic idea: Gather site registrations for a domain name from the network and from friends -> calculate your WoT metrics for each of the results -> pick the top site if one stands out at the top as most trusted -> let the application go to that site.


Every participant runs a WoT-DNS client. There are several ways to enable browsers and IM clients, etc, to use this system. One is to run a local proxy where only .wot domains are intercepted, and normal traffic are untouched. When connecting, it would start by asking the WoT-DNS network about who has registered their site with that domain name.

Every client has a unique asymmetric keypair, both regular users and servers have them. Servers additionally generate one unique keypair per registered domain. Registered .wot domains are identified by their key. Each registered domain has at least two addresses: The readable one, such as example-domain.wot, and one that contains it’s public key hash (like I2P, [the 52 base32 characters of the SHA256 hashed public key].key.wot, so “key.wot” are one of those domains you can’t register). That means you can always go directly to a particular site by entering it’s key hash.

A domain registration has to contain at least this: The domain name, the server’s public key, addresses (yes, more than one if you like, useful for load balancing and to additionally specify I2P/Tor addresses along with regular-internet IP addresses). Additionally, you can add all the data that ordinary DNS servers can hold for a domain. Also, it can hold a site name and a description of the site, which is useful for telling sites with the same domain name apart. All registrations are also timestamped. I would also like to see a trusted timestamping system built in, to ensure that nobody claims that their domain registrations are older than they are, and the point is to prevent phishing by faking a site’s age.

Domain registrations are stored in a distributed database. This means that every node keeps local copies of plenty of registrations. Updates will be continously added to the distributed database (such as when IP addresses change), and the old registrations are then replaced (but only if the keys and signature match). I suggest that we use some DHT system (“distributed hash table”) like Kademelia for the database, or something similiar that provides the features we need.

The Web of Trust part:

The keypairs make this possible. Since everybody has a unique key pair that consists of a public key and a secret one (using asymmetric cryptography, public key encryption), PGP makes it possible to create signatures of data that likely can’t be forged in our lifetimes. 2048 & 4096 bit keys using RSA are highly secure (while I prefer larger and safer 4096 bit keys, they’re unfortunately also about 5-6 times slower). Keypairs are both used by the site owners for signing their domain registrations, as well as by users that additionally sign them as a means to show that they trust that that site. You can also sign a site as untrusted.

WoT details: You have a list of trusted people and organizations, including their public keys. Organizations like Verisign (SSL certificate authority) could be predefined for the sake of newcomers, this will make it like SSL out of the box. If a site has been signed by a friend or by a trusted organization your client will detect that and calculate what level of trust (trust metric) that site gets based on it. Since there can be several sites for a domain name, the site with the highest trust metric are the site your client chooses to go to. If both Microsoft and a spammer registered microsoft.wot and only MS has a signature from Verisign, then Microsoft’s site will be more trusted so your client will prefer to go to Microsoft’s site if your client is set to trust Verisign.

If the site in the top don’t have a trust metric that’s high enough (not enough trusted signatures or less than around 30% higher trust than the runner-up) it triggers some an alert (some spam/scam detection should also be built in), then you won’t be sent to the top site right away – instead you get a list of the matching sites, ranked by the trust metrics.

So, how are trust metrics calculated? There are PLENTY of ways. One is to assign various levels of trust to your friends, and then simply take a look at how trusted a site is by the people in your web of trust, such as your friends friend. If it’s fully trusted by somebody you fully trust, then you fully trust the site. If it’s a bit trusted by somebody you trust a bit, it’s just a little bit trusted by you. And that’s just the short version!

Note that a signature of a domain from a user or organization as Verisign aren’t intended as a method to indicate how trustable the site owner is, it’s primarily a means of voting in this case (choosing who gets what domain name). The trust part is secondary, but necessary to make sure that scammers and spammers won’t be able to take over popular domain names to trick people.

So how do you get started? If you want to clear out Verisign and those from the predefined list because you don’t trust them, how do you add people you trust? Well, one way is to “bootstrap” using social networks. Let your client announce on Facebook, Twitter or Google+ that you now are using WoT-DNS with a message that contains the key. When your friends start using WoT-DNS, their clients will automatically find your key and connect to you (if they choose to connect to the same social network). Then you’ll have a list of your friends in your client, and can set the trust levels there. And we don’t need to limit it to social networks.

For site admins: While sites will have one keypair, it’s not the only one. Your client also have your personal (or corporate) keypair that your site’s key will be signed with. This “master keypair” for that site can be kept away from your servers, so you can keep it encrypted on a drive in a safe (obviously you can have multiple separate keypairs, so you don’t need that level of security for the rest). If the server is hacked and somebody get your site key, you can issue a revokation signature with your master key pair, which will tell everybody that the site’s old keys now are revoked.

Then you can restore the servers and generate a new site key, and all the old trust signatures can be “moved over”. This won’t be automatic, but everybody who has signed the site key will get notified about the replacement key pair so that they can sign it.


  • Vulnerable to targeted social engineering. A scammer could try to trick several close friends of some CEO to sign his site, in order to convince the CEO that his site is legitimate.
  • Trust metrics. How do we calculate them? How do we make them hard to “game”/mess with?
  • Evaluating trust. How do you know if your friend can judge if a site is legitimate? How do you yourself know if a site is legitimate?


  • Botnets/spammers that mass-sign phishing sites’ keys. This is only a problem if a significant part of YOUR Web of Trust (your friends) sign the site’s public key and it hasn’t been flagged yet by somebody like Microsoft or Google (they keep their own blacklists already for spam domains for use in Chrome and IE).
  • A bunch of strangers or Group X or Group Y signing the key for a site that’s in conflict with the one you want to go to from Group Z. This will NOT prevent you from getting to the site you want. Just don’t set your client to trust X or Y. But yes, this means that followers of different groups can end up on different sites for the same domain name. This is by design, as I can’t come up with any other solution that isn’t first come, first serve, and that would make domain names globally unique. So I’m allowing domain name conflicts and letting different people get to different sites for them. I do not see this as an issue.
  • Non-static URL:s. We can have those too, but you need to use the key hash domain names. A static URL could look like this: abcdef0123456789abcdef0123456789abcdef0123456789abcd.key.wot/news/global/reddit-is-awesome.php
  • Single point of failures/hacked Certificate Authorities. Remember that we are computing a site’s trust based on what ALL of the nodes that WE trust think of it. A single flag from somebody you trust could alert you about a malicious site. If Verisign were to be hacked, it could be a flag from StartSSL. Or from somebody else. Doesn’t matter. All it needs is one warning. But the scammer has to trick almost everybody you trust into trusting him.

Feedback and questions, please! Please contribute by giving me feature suggestions, or by pointing out possible problems, or by just telling me about any useful idea you might have. All feedback is welcome! If you don’t like my idea, tell me why!

[This is not finished yet, it’s a work in progress…]

Tamper resistant full-disk encryption

There are various problems with many of the common methods of applying full disk encryption (FDE) that isn’t always obvious right away. The common FDE programs also typically have a number of limitations or drawbacks that make them less than ideal.

One class of attacks one wouldn’t necessarily consider is called evil maid attacks (tampering with the ciphertext, altering the bootloader), another is comparing different versions of the ciphertext over time. One particular type of tampering attack is a ciphertext modification attack against certain implementations of CBC cipher mode, which allows the attacker to essentially replace parts of the plaintext by altering the ciphertext in a certain way (which however will randomly scramble the first block in the series that you tamper with). For most FDE variants you can see exactly which parts of the ciphertext has changed and which changes has been undone (a previously seen ciphertext block returns), and much more. There is also the risk of an attacker simply reversing selected parts of the ciphertext to a previous version, which in some cases could reintroduce vulnerabilities in software that is in the encrypted volume. Some methods of getting around the problems is highly complex, and don’t always solve all of the problems.

I’m suggesting one way of implementing full disk encryption that should be secure against a wide range of attacks, even against an attacker in full control of the storage space such as a compromised cloud storage host, both preserving secrecy/privacy and ensuring any tampering with the data can’t be undetected.

First of all we need to be able to encrypt blocks of an arbitrary size, because that’s one of the limitations with trying to implement efficient full disk encryption as the smallest writable block can have varying sizes. XTS mode handles this, has good performance and is widely used.

While it doesn’t allow you to tamper with it in a way that can control the plaintext (unlike CBC) one can see on the ciphertext when the plaintext have been reversed, and when used alone it don’t stop an attacker from reversing the ciphertext to a previous version or scrambling it (which could allow an attacker to reintroduce security holes in software, or to scramble plaintext undetected). So we need to add authentication to the encryption so that modified ciphertexts will be detected, and further add a method to make sure that no individual blocks can be reversed to previous states.

Exactly how it should be implemented isn’t my expertise, but the most simple (but inefficient) method would be to generate authentication tags through using HMAC on all XTS blocks, and then further HMAC that list of HMAC’s such that they can’t be individually reversed, and store it encrypted. The method I’m suggesting later will have some similarities to that method. Ideally I would want a type of authentication tag generation integrated into the XTS cipher mode, or some other efficient method of generating authentication tags. Another approach would be to generate something like a Merkle hash tree of the ciphertexts and HMAC that as the authentication method, which allows you to save space as you don’t need to store all the authentication tags (generating it might not be very efficient, however). Yet another option (in case it would end up performing better) would be to combine those two and use an authenticated version of XTS and generate a Merkle hash tree of the tags for storage rather than storing them directly. The ideal solution is some form of authenticated block cipher which can handle arbitary block sizes.

Then we need to make sure that any attacker can’t easily see what you have changed in the encrypted volume. To do this, I’m suggesting that each time you mount the disk as writable you generate a new encryption IV (or key) for that session, which is used to encrypt all blocks you edit. This IV is also used to generate the key for the encryption authentication for the session. All generated IV:s are encrypted with the master key, and there’s a means of tracking which block is encrypted with which IV (some form of database). The IV list is also authenticated together with the list of authentication tags such that modifying any single block in the volume, even replacing them with previous versions, would lead to the authentication of the ciphertext failing (as it would only validate if the the stored authentication tags for the latest version of that block verifies for that ciphertext).

To improve the security of this approach, one could use a form of ratcheting where each new IV or key is derived from the last key, a counter and fresh collected entropy. Using a counter together with the above approach of making sure everything is authenticated also enables you to ensure the entire volume is intact, and that nothing have been replaced with a previous version as all you need to see is that your software decrypts the volume successfully without warnings and that the counter is one number higher than last time, because an attacker can’t get your software to show a slightly higher counter value and also not warn about tampering without knowing your encryption password.

On top of that one can also add features like read-write access controls by adding in public key cryptography. Use a public key from a master keypair that is stored in the header, together with a signed ACL and signed public keys of everybody with editing rights. These keys would be required to sign the IV/key list as well, such that somebody who only have the decryption password but not a a keypair with editing rights can’t make any edits without the cryptographic authentication failing. Detailed ACL:s would require some form of support in the OS to not cause errors, potentially this could be done by treating sections with different access rules as separate volumes, some of which would be read-only.

One way to speed up detection of attemps to modify the ciphertext is random pre-boot verification of a subset of authentication tags. Checking a few hundreds to a few thousand tags can take less than a second, and has a high probability of detecting modifications if an attacker (or a disk error!) has caused any part larger than a few thousand blocks in a row being modified. After boot, on-access verification is performed and blocks which verification fails for is reported as corrupted to the OS.

Then further we need to make sure that an attacker can’t easily tell exactly which parts actually have been modified each time, and the easy way to do this is to randomly select additional ranges of blocks to reencrypt with the new session IV, which you didn’t touch yourself. Once a previous session IV no longer is used for any blocks (all blocks that was encrypted with it has been overwritten) it can be deleted from the IV list. Another way could be to randomly reorder sections of blocks, like reverse defragmentation.

%d bloggers like this: