I've noticed that since I published the How to Backdoor Diffie-Hellman paper I did not post any explanations on this blog. I just gave a presentation at Defcon 24 and the recording should be online in a few months. In the mean time, let me try with a dumbed-down explanation of the outlines of the paper:
I found many ways to implement a backdoor, some are Nobody-But-Us (NOBUS) backdoors, while some are not (I also give some numbers of "security" for the NOBUS ones in the paper).
The idea is to look at a natural way of injecting a backdoor into DH with Pohlig-Hellman:
Here the modulus \(p\) is prime, so we can naturally compute the number of public keys (elements) in our group: \(p-1\). By factoring this number you can also get the possible subgroups. If you have enough small subgroups \(p_i\) then you can use the Chinese Remainder Theorem to stitch together the many partial private keys you found into the real private key.
The problem here is that, if you can do Pohlig-Hellman, it means that the subgroups \(p_i\) are small enough for anyone to find them by factoring \(p-1\).
The next idea is to hide these small subgroups so that only us can use this Pohlig-Hellman attack.
Here the prime \(n\) is not so much a prime anymore. We instead use a RSA modulus \(n = p \times q\).
Since \(n\) is not a prime anymore, to compute the number of possible public keys in our new DH group, we need to compute \((p-1)(q-1)\) (the number of elements co-prime to \(n\)). This is a bit tricky and only us, with the knowledge of \(p\) and \(q\) should be able to compute that.
This way, under the assumptions of RSA, we know that no-one will be able to factor the number of elements (\((p-1)(q-1)\)) to find out what subgroups there are. And now our small subgroups are well hidden for us, and only us, to perform Pohlig-Hellman.
There is of course more to it. Read the paper :)
If you want to generate good randomness, but are iffy about
/dev/urandom because your machine has just booted, and you also don't know how long you should wait before
/dev/urandom has enough entropy, then maybe you should consider using
getrandom (thanks rwg!). From the manpage:
By default, getrandom() draws entropy from the /dev/urandom pool.
If the pool has not yet been initialized, then the call blocks
Also it seems like the instruction RDRAND on certain Intel chips returns "true" random numbers. It's also interesting to see that it was audited twice by Cryptography Research, which resulted in two papers, the recent one being in 2012 and done by Kocher et al: Analysis of Intel's Ivy Bridge Digital Random Number Generator.
I am learning about generating an elliptic curves cryptography , in your notes I find:-
JPF: Many people don’t trust NIST curves. How many people verified the curve generation? Open source tools would be nice.
Flori: people don't trust NIST curves anymore, surely for good reasons, so if we do new curves we should make them trustable. Did anyone here tried generating nist, dan, brainpool etc...? (3 people raised their hands).
Would you give me some reasons for generating our own curves? what are the good reasons that some people do not
trust on NIST CURVES?
Hello Mr. HAGER
Well, the history of how standard curves were generated has been pretty chaotic, and djb has shown that this might be a bad thing for us in his Bada55 paper.
NIST says that they generated their curves out of the hash of a sentence that is unknown and lost. The german Brainpool curves seem to ignore their own standards on how to generate secure curves.
one of the standard Brainpool curves below 512 bits were generated by the standard Brainpool curve-generation procedure
So how bad is it? We know that choosing random parameters for your crypto algorithms can lead to unsecure or even backdoored constructions. See how to choose Sboxes in DES, how to choose nothing-up-my-sleeve numbers for hash functions, how to choose secure parameters for Diffie-Hellman, how Dual EC is backdoored if you know how the main points P and Q were generated, ...
Well, so far we don't really know. The fact that we haven't been able to crack any of the curves we use is "reassuring". I like to look at bitcoin as a proof that at least one of them hasn't been broken :) But as many researchers suspect, the NSA might be years ahead of us in cryptanalysis. So it is possible that they might have found one (or more) issues with elliptic curve cryptography, and that they generated "weak" curves before publishing them through NIST's standards.
So far, there hasn't been enough advances in ECC (a relatively old field in cryptography) to make you worried enough to generate your own curves. Some people do that though, but they know what they're doing. They even released a paper on how to generate safe curves using nothing-up-my-sleeves parameters. Like that, you can review the generation process and see that nothing was done to harm you.
Some people also worry about sparse primes, and that's one more paranoid reason to use random curves as above.
But seriously, if you don't want to go through all the trouble, you should probably start using one of the curve specified in this RFC: Curve 25519 or Curve 448. They use state-of-the-art research, reproducible generation and have been vetted by many people.
Blackhat and Defcon are almost here! I'll be landing there on Friday 29th and will give a crypto training at Blackhat, then on the 5th will give a talk at the Defcon Village track about Diffie-Hellman and backdoors.
If you have any interest in cryptography and want to meet up say the word! We should probably organize a drunk cryptographer evening (anyone interested?)
Also, I should be looking in what talks are interesting, if you think a particular one is please share in the comment section =)
I was at the offices of Braintree this evening, talking about the history of TLS, backdoors and Diffie-Hellman. If you missed it, my paper was released a few days ago and this is the talk that is packaged with it =)
my colleagues and I preparing the event in the beautiful atrium of Braintree
starting the talk!
Someone asked me for the slides, you can find them on the github repo. You can find the
.keynote file as well containing videos (but you need osx).
I'll be looking into submitting this talk to conferences, if you have any idea where I'll be happy to hear suggestions =)
My latest whitepaper just got published on ePrint. It's available here.
Looking to seek answers to the recent Snowden revelations and the history of state agencies backdoors, this paper looks at what the secret spies might have been researching in order to find new ways to observe and tamper with the people's traffic. What if we just sabotaged one of the most trusted cryptographic algorithm of the last 40 years? What if we backdoored Diffie-Hellman?
Next week on wednesday NCC Group will host its second open forum in Chicago. And I'll be one of the speaker!
If you are interested in crypto, I'll be talking about backdoors and Diffie-Hellman. This will be the occasion of explaining what my latest whitepaper that was released today is about.
John Downey will also be talking about "Cryptography Pitfalls".
By the way, if you're interested in such events in Chicago. OWASP was today (and we even learned how to brew beer there). There are also other security related events that you can get update on from this twitter.
Ahsan asked me:
Sorry i am using DTLS 1.2 instead TLS 1.2. Kindly explain the structure of finished message, like how many bytes for "nonce", how many bytes are encrypted data and how many bytes for authentication tag.
I'm writing this because I want to clear things up: you can ask me pretty much anything and I'll do my best to answer here. So please ask away if you have a question in crypto! There is also a contact form for that.
Differences between DTLS and TLS
TLS is an application layer protocol. Some people say that it's a transport layer protocol. This is false. It runs in whatever program you are using on top of TCP/UDP. Although it is used to transport the real content of the application: it can be seen as an intermediate transport layer running in the application layer.
The TLS we know, the one that runs in our browser, typically runs on top of TCP. But in some situations, the developer might want to use UDP to exchange packets. Since UDP forgives packet loss (think multiplayer video games or audio/video conferences), it is important that TLS is setup accordingly to forgive those packet loss as well. For this, we use a similar but different specification than TLS: DTLS.
DTLS is what you use if you need TLS on top of UDP.
The main DTLS RFC documents the differences with TLS. Most of them are modification to the protocol so that the connection doesn't terminate/break if a message is lost, duplicated, out of order, etc...:
- records can't be split into several datagrams
- the sequence number is written in each record
- errors (duplicates, loss, out of order) are tolerated
- no stream cipher can be used (no state can be used if errors are tolerated)
- protections against DoS attacks (apparently DTLS has some problems with DoS attacks)
The simplest TLS handshake goes like this:
- the client sends its ClientHello packet
- the server replies with his ServerHello packet
- the client sends (his part of) the shared secret in a ClientKeyExchange packet
Now I omitted a bunch of packets that are usually part of the handshake as well. For example:
- the server usually sends his certificate after the ServerHello message.
- the server might also take part in the creation of the shared secret in some modes (including ephemeral modes)
But this is not what is interesting to us here.
After enough messages have been sent to compute the shared secret, a ChangeCipherSpec message is sent by both the client and the server to announce the beginning of traffic encryption. Followed directly by an encrypted Finished message authenticating all the previous handshake messages.
In my knowledge, the Finished message is the only encrypted message of a handshake. It is also the moment where the handshake is "authenticated" and where Man-In-The-Middle attacks usually stop.
Now what is in that Finished message?
Exactly the same things as in TLS. The TLS 1.2 RFC shines a bit more light on the subject:
verify_data = PRF(master_secret, finished_label, Hash(handshake_messages)) [0..verify_data_length-1];
For Finished messages sent by the client, the string "client finished". For Finished messages sent by the server, the string "server finished".
Don't forget that this Finished structure is then encrypted before being sent in a record. The Hash and the PRF we already defined in previous posts, the
handshake_messages value is what interest us: it is the concatenation of all the binary data received and sent during the handshake, in order, and not including this Finished one.
Now DTLS has the particularity that some messages are re-sent, out of order, etc... so duplicates must be ignored, real order must be preserved.
How do I know that?
Besides reading the RFC, you might often want to know what's happening for real. To be a bit more informative, let me tell you how I quickly get that kind of information when I'm curious:
- I setup a server key + certificate:
openssl req -x509 -new -nodes -keyout key.pem -out server.pem.
- I start the server:
openssl s_server -dtls1 -key key.pem -port 4433 -msg.
- I connect to it with a client:
openssl s_client -dtls1 -connect localhost:4433 -msg.
-msg argument will print out the exact content of the messages sent. In the case of the Finished message, it will show the unencrypted hexadecimal data sent. If you want to see the real encrypted data that is sent, you can use the
You might also want to have a bit more information about every records. A good way to do this is to record the traffic with tcpdump:
sudo tcpdump udp -i lo0 -s 65535 -w handshake.pcap and to open the
.pcap file in Wireshark and enter
udp && dtls in the filter area.