SPEhosting, on 22 November 2012 - 23:14, said:
if the key problem is the middle man ... why encrypt at all ? isnt the point of encryption to screw over the middle man in the first place?
Of course it is, I'm not sure that I follow...
With both public-private key cryptography and DH, an exchange needs to take place of a piece of information crucial to establishing a secure channel of communication. In public-private key cryptography, this is the exchange of each other's public keys, in DH, this is a few numbers. In both cases, if this is observed only, it doesn't matter, the channel will be secure, however if an attacker is sitting between the two of them and intercepts this exchange then we do not have a secure channel, although it may look like it from the perspective of the two users. It's secure between Alice and the attacker, and between Bob and the attacker, but the attacker is silently decrypting, re-encrypting, and re-transmitting every message.
What you need is a way of ensuring that this data has really reached its destination, and not been intercepted and switched with the attacker's own. This is the tricky part. The proper way to do this is for the two users to communicate in another way, to verify that what they have received is correct (or to have agreed on a shared secret at some point in the past), which could be done for example by talking over the phone (if you'll recognise their voice and you're sure an attacker will not have the capability to intercept that and pretend to be them), or by meeting in person.
This is obviously a hassle, but with public private key cryptography can be minimised. For example, Alice and Bob meet in person to exchange keys, and they sign each others keys. John is friends with Alice and meets in person to exchange and sign keys. John then befriends Bob and wishes to communicate securely with him. Since Alice has already signed Bob's key, and John already trusts Alice's key, John does not have to actually meet with Bob. All that's needed to trust a new key is that at least one signature on it is from a key that you already trust. (Note that the work of exchanging keys and signing do not have to actually be done during the meetup, the keys could be exchanged beforehand, and just the key's shorter "fingerprint" compared. The signing of each others keys could be done later and uploaded to a public key server, so John here can get a copy of Bob's public key with Alice's signature already attached).
I suggested that this verification might be a problem for your system, it depends on people knowing each other in real life, or rather knowing at least one of the other users in real life, and establishing a network of trust through signing of each other's public keys. I outlined another option that you could take, which is to allow the web server to act as a "legitimate" middle man. Every user has a copy of the server's public key, and so can securely transport a copy of their own public key to it, and the server can then securely transfer it to the other user. It would not be possible for an attacker to compromise either key exchange. This simplifies things for the users who no longer need to meet up and verify something, however the server itself is a big weak point. The admin of the web server has the power to intercept communications, the government may force the admin to do so on their behalf, or an attacker could potentially break into the server and compromise everything. Whether you choose do this is your decision to make, I just wanted to cover it as part of my analysis. For users who do know each other in real life and are willing to do a proper exchange, this option would be much worse for them, but for users who do not know each other, even through a chain of other users, and therefore cannot validate each other's keys, as long as they are establishing connection to the right user on the system, public keys can be exchanged securely (with the exception of the server itself, which they would have to accept a compromise on).
Evn suggested that our goal should not be to try and know that a particular person owns a particular public key, but simply that once you've got a public key, that all future communications are coming from that same key, which is easy. This is indeed easy, however as I said in my reply, if the original communication was intercepted by an attacker, then by verifying that it's the same key, all you're doing is verifying that the same attacker(s) is still watching and no other attackers have joined in.
Evn also talked about the difficulties in obtaining the correct public key
without a proper "meet up" type verification, which needs to involve some level of trust. Trusting a single service to store your public key would be foolish, because the service could just swap it out with one they've generated themselves. Evn suggested that storing it in multiple places, comparing copies from multiple places, and allowing the owner of the key to dictate where you go to get them from is much better, and I agree. However, this is by no means perfect. Firstly a powerful entity, e.g. the government, could easily have the capability to compromise this, by intercepting every transfer of a key on to and down from the internet. Additionally, without meeting in person, or talking over the phone, if instead Alice tells Bob through some digital communication which location(s) to visit to get the key, there's no guarantee that communication itself isn't compromised, or perhaps the user types in the correct url (or clicks the correct link), but it's invisibly redirected to a certificate owned by an attacker such as the government. There is absolutely no possible way to be sure that the exchange hasn't been compromised without meeting the other user in person, and checking with them.
Evn has now taken this even further to talk about the issue of knowing whether a person you don't already know really is know they say they are if you meet in real life to do the key exchange. This is certainly an interesting topic, and obviously only applies to people you don't already know. Someone you do already know might of course be lying to you about their identify also, but knowing that would be besides the point, you simply want to talk to that individual securely, no matter their real secret identity. With someone you don't know, let's say one of us wishes to talk securely to another, and need to do a secure key exchange, if we met in person, how would we know if the person we meet is the right person? In such a case all you can really do at the end of the day is make a judgement call, based on the real life likely hood of their being imposter, etc.
What we need to do here is take a look at the people who might be using the system and how they know each other.
- If all users of the system already know each other, i.e. you're just building this for use by your group of friends, then the best solution will be to establish a chain of trust by signing each other's keys until everyone has at least one signature from someone else in the group.
- If you're involving users who do not know each other in real life but do know each other through some other means, verification could be done through those other means. For example with us, we could verify each other's keys through Neowin. We would have to each assess the likely hood of our exchanges being compromised (e.g. by Neowin, by our ISP, by our government), and just accept that it's not a 100% guarantee, but probably not likely.
- If you're dealing with people who have never met each other, one of them has simply discovered the other through a chat service and initiated a chat session, then there's absolutely no way to guarantee security. However the method of having the web server as a "legitimate" middle man has advantages in some ways here.
Another interesting aspect to think about in all of this that's not been mentioned yet, is what if an attacker compromised the client application itself. I.e. you publish the software on a website, a user goes to download it, but an attacker has hacked the server and replaced it, or intercepts the download and serves a hacked copy instead. You'd need to take that into consideration also. To solve this, you'd need to sign the application, and provide your developer key to users. As a user, ensuring that the developer key that you have is correct has the same problems as already discussed.