Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Show HN: Terminal-based group chat with end-to-end encryption (github.com/jeztek)
60 points by jeztek on July 4, 2013 | hide | past | favorite | 41 comments


Hey all, great discussion. Apologies for not chiming in earlier, I posted this to HN in the morning and left for 4th of July activities, certainly not expecting it to make the front page. Here're some thoughts and clarifications:

* No, I am not a cryptography expert. I've had a nascent interest in the field for awhile and this was my way of getting my feet wet while scratching an itch. I thought I'd post it on HN to get feedback and see where I might have screwed up.

* I'm here to learn. *

We all have to somehow right? A disclaimer is a good idea, I'll add it to the README.

* The project was originally motivated because I couldn't find a group chat service that provided an IRC-like experience with end-to-end encryption. The closest I could find was FiSH-irssi, an irc client plugin:

https://github.com/falsovsky/FiSH-irssi

I wanted to try implementing something that was easer to use. I ruled out IRC over SSL because the conversation is cleartext at the server.

* I should have mentioned this in the README and will update it -- The design goal for this system is to enable a group of trusted friends to communicate with each other over an insecure channel without fear of eavesdropping. It is assumed that a member of the trusted group operates the server. Forward secrecy was an additional goal facilitated by changing the room key. It sounds like my implementation did not achieve the design goal. What can I do to make it right?

* My intention was for the secret room key to be securely shared following the RSA key exchange protocol (encrypt secret with requestor's public key and sign with sender's private key, decrypt with requestor's private key and verify with sender's public key). The problem then lies in how to properly exchange users' public keys. If I trust the server but don't want the server operator to read my conversations, is it not okay to facilitate public key exchange through the server?


Learning is fine, just add a disclaimer that it's actually probably not so secure. Oh please don't get me started on FiSH, and PLEASE don't model anything after fish. I had the same problem as you, there's no useable crypto for irc.

- The FiSH plugin for Xchat has a (possibly remote) buffer overflow in the Diffie-Hellman key exchange.

- FiSH uses ECB mode. Seriously. ECB.... ECB... might as well use no crypto.

- IIRC FiSH wastes two bytes per 8 byte block the way it does Base64, not sure about this anymore, it's been a while.

So I tried to find a better plugin and mod it a bit which I did (https://gitorious.org/fishslim/dumfish). But I didn't realize back then that FiSH uses ECB mode.

Since the DH key exchange is not authenticated it's useless. So I dropped it and hacked my own (for Xchat, https://github.com/lawl/dumfish), which doesn't offer DH key exchange but CBC mode instead of ECB, we exchanged keys manually via OTR. (And just makes me realize I also don't have a disclaimer, so I'll add this now.)

Disclaimer: Also not a cryptographer, so it's probably not secure. Do not use for anything serious.

If you want to look at a secure protocol, please look at OTR: http://www.cypherpunks.ca/otr/


Wow.

> WARNING: Unable to decrypt. One of you may have changed keys or might be an imposter. Run /idexch if you trust this person.

This may very well be the worst advice you could possibly give.

Suppose Alice and Bob already have a conversation. Then Eve wants to start MITM'ing during middle of the conversation and has already missed the key exchange (where she could easily switch Alice and Bob's public keys because your application doesn't even try to authenticate). Now she just needs to corrupt the packages so your app tells them to do a key exchange again and now can easily switch alice and bobs public keys for a set of her own ones and read everything.

Key exchanging is the hardest problem your app would have to overcome to actually be secure, telling your users to just do it again over an unauthenticated connection is just ... stupid, sorry.

Plus from glancing over it it lacks things like session keys etc.? Though that might well be in the NaCl lib, so I'm not sure about this.

I'd just ask you to label this as POC or something, because no one should use this application for anything that needs to even remotely stay secret.


This is one of the reasons why I think HTTPS isn't as secure as many perceive. Users have become so acclimatised to ignoring SSL warnings due to mixed content, expired or self signed certs and browsers have made it so inconsequential to skip said warnings that many users wouldn't think twice about ignoring those errors if there was a genuine MITM attack.


That's fair, I modeled some aspects of the system after FiSH-irssi, which also doesn't have user authentication or MITM attack mitigation. That'll teach me to post to HN prematurely. Both SSL with proper endpoint authentication (and session keys) and user authentication are on the todo list.


kba, your comment is dead, though insightful.


In case people are wondering what stavrosk is referring to, kba wrote:

I'm tired of people labeling their applications as "cryptographically secure" with no proof of correctness or any kind of guarantee. It's just a blunt and stupid statement.

The author of this clearly has no cryptographic expertise and just wrongly applied a cryptographic scheme.

In the description, it reads "[..] messages are encrypted and decrypted at the end points such that malicious machines on the network cannot eavesdrop on the conversation, including the chat server," but no effort is made in the client code (client.py) to ensure the server works as it should. Yes, the server can't eavesdrop on the data as-is, but that means you have to trust the hosting provider is using exactly your server.go, thus you have to trust the server completely after all. And if you do, why bother trying to hide it from the server in the first place?

I'd feel even less safe using this than IRC over SSL.

The major problem with this is that you're trying to do something impossible. In order to have a secure connection between two or more people, you need to either have a key in place or establish one. Both of these options are extremely hard to achieve.

In the former, you have a to get a key in place (which can't get transferred through the server for obvious reasons), so that has to be established before any confidential data is being transferred. This is clearly not happening.

The latter option is a key exchange protocol such as Diffie–Hellman. This can work; you can in fact make a key exchange between two parties where an eaves-dropper will be none the wiser for listening in. But then you have another problem: authenticity. You have no guarantee that you are in fact talking to who you think you are.

Your system makes no effort to overcome either of these challenges.


In response to kba:

deadchat implements the latter option. The secret room key is shared using the RSA key exchange protocol but you're right, there's currently no way to guarantee that you're talking to who you think you are. User authentication is on the todo list.

I think there's still value in hiding the conversation from the server even if you must still trust the server to not behave maliciously. If some three-letter agency contacts the server operator asking for a back channel to listen in, he or she could respond that it's not possible without malicious intent towards a user:

http://www.macobserver.com/tmo/article/apples-imessage-encry...


Please, please, please, please, please, stop releasing hobby applications that use cryptography. You're bound to do it wrong. Please stop it.


Can you point to a flaw in the cryptography? Otherwise, while I understand where you're coming from I think your criticism is misguided. Cryptography is very interesting and is fun to implement. It is also difficult to get right. Does that mean hobbyists shouldn't implement it? No, it just means that you shouldn't expect security from hobbyist implementations. I find it disconcerting to see comment after comment on HN tearing people down for working on projects that interest them.

The point of criticism is to help people improve. By effectively saying, "You're not cut out for crypto, don't even bother," you do a disservice to others and contribute negativity that HN doesn't need.


It would be very much easier to ignore hobbyist implementations of crypto if they came with suitably huge warnings.

"This is just a proof of concept. It's not secure. It's just a learning exercise. Don't use it for anything other than learning."

I haven't looked at this project, so maybe it does have those warnings.


How will people learn if they don't try?

The problem is not creating and releasing such applications; the problem is overclaiming their security, or putting early confidence in them.

Crypto is hard, we get it. Beginners and non-experts are going to mess it up, we get it. Even experts almost always mess it up, we get it.

Still, a good programmer of crypto software (or even just, "wise user of battle-tested crypto libraries in the proper ways") will almost always start out as a bad programmer of crypto software... who got started, and learned by failing.

To borrow an aphorism from other project/product wisdom: if your first version's crypto isn't obviously and embarassingly broken, you waited too long to release.


Broken social networking websites and YouTube clones are relatively harmless, so that philosophy makes sense.

Broken cryptography can cause loss of money, infrastructure, and life. Imagine if a group of dissidents where to start using this program, the crypto implementation was subtly wrong somewhere, and they were disappeared by their government early one morning. Imagine if some transmitted a password through what they thought was a secure chat, and that password led to an industrial control system for, say, a subway, water treatment plant, foundry furnace, or explosive chemical storage tank. Software doesn't just move Tweets. There are massive, hot, high-voltage, fast-moving objects controlled by software also. Letting people believe information is safe when it isn't can have very real consequences.

Unless it is obviously written all over your software that "THIS IS A TOY AND YOU SHOULD NOT EXPECT IT TO ACTUALLY KEEP ANYTHING SECRET," your obviously and embarrassingly broken crypto (to a crypto expert) might look just fine to a nontechnical user with dollars and/or lives riding on your product.


Crypto experts are not beautiful or unique snowflakes, armchair or otherwise.


Yes, so the message should be: "add disclaimers, avoid promoting where rigorous security is required, educate yourself on best practices".

Not, "stop releasing hobby projects".

The reckless non-technical user who grabs any project that mentions a slight sheen of crypto-sparkles, and then trusts that software with their life or savings, is doomed anyway. The existence of one more hobby project with amateurish crypto isn't going to kill or bankrupt him twice over.


I'm okay with hobby projects that use cryptography if every time the user tries to do anything in which security can be expected they flash a message that makes the user type "I understand my data may be read by an adversary."


Yeah, my question is what is anyone supposed to do? What if we want something to be secure? Are we supposed to just say "well, I'm never supposed write anything involving crypto"? How do we do things right? Seriously.


No. You learn to do cryptography. You get a book, you sit down and you read it. Understand what are cryptography primitives. Understand how they can be used together to create cryptographic systems. Understand every part of that system. Then learn what are the common errors, learn how misuse of cryptographic primitives can lead to disaster. Be able to talk for hours about why WEP encryption can be easily cracked by a low-powered netbook.

When you've done all of that, you'll know that you are abysmally incompetent at cryptography. When you know that, you can start learning how to become good at cryptography. Some people divide learning in four steps: unconscious incompetence (you don't know that you're bad), conscious incompetence, conscious competence and unconscious competence.

Even when you're competent, you will make mistakes, because cryptography is very hard. We've seen how MD5 is now broken, yet still people use it as message authentication ciphers even when it's trivial to perform a length extension attack. But MD5 wasn't always broken. I'm sure it was designed by competent people, but they can't foresee all flaws.

That is why someone who is incompetent at cryptography should not do it.


(I'm very much not any kind of expert on Crypto but...)

Probably when you understand "Applied Cryptography", front to back, maths included, then you can think about writing cryptographic software.

Or win a fist fight with Schneier.


Slightly tangential, but can people please stop naming their software "salt"? This is like the 4th or 5th relatively high profile project I've seen with that name recently :/

More on topic - does anyone have any good reference guides for how to not suck at cryptography, preferably more "API guide for programmers in a hurry" than "maths textbook for people who want to learn the inner details of algorithms for their own sake"?

(I know that knowing the internals will make you a better programmer, but it seems there are a lot of people who don't know the internals or externals of cryptography, and having a step-by-step cookbook which can be followed blindly would make this situation slightly less bad. Sure it might give people a false sense of security - but they already have a false sense of security from rolling their own crypto, so a cookbook couldn't be worse :P)


I think if you are a "programmer in a hurry" you should stay away from crypto.


The problem is really that doing crypto "right" has a lot of very subtle very complicated corner cases that are very easy to get wrong if you don't fully understand the internals. I'm not an expert on crypto, but I know enough to know I wouldn't ever dream of rolling my own. Your best bet is to get one of the well established (and well regarded) crypto libraries, pick a suitably large key length (if in doubt, go larger), and follow the documentation exactly.

Even using a good crypto library won't save you if you don't follow the docs or try to get creative with the API. For instance, using multiple passes of different encryption algorithms won't necessarily improve the strength of the encryption. Due to subtle mathematical interactions it can often lead to exploits that wouldn't have existed in the individual algorithms, but do exist in the combined algorithm. Similarly doing encryption quickly might seem like an important goal, but often consistency is more important lest you inadvertently create a potential timing attack.

TL;DR; Use a good crypto library, a large key size, a good source of entropy, and follow the documentation exactly, don't try to get creative with it.


Short answer: Use PGP, TLS/SSL or KeyCzar.


Maybe it's due to the name, but the "other" salt, saltstack, apparently had a serious problem with cryptography: https://github.com/saltstack/salt/commit/5dd304276ba5745ec21...


I'm a little confused by this. How can it be a group chat with end to end encryption? Surely everyone logged into the chat room would need to read the messages, so it's really no more secure than IRC over SSL. Or is this actually more like a peer-to-peer instant messenger?


I haven't looked at the code itself, but based on the usage section it seems like everyone in the room shares a secret key. I think the concept is that in order to get the secret key, you have to explicitly be given it by someone in the room.


By the way, there's an already-existing secure group chat software, SILC, that does something similar: https://en.wikipedia.org/wiki/SILC_%28protocol%29 (see "security" section, and technical details in http://www.silcnet.org/support/faq/crypto/ )


Don't we already have a secure chat protocol, SILC? Is that not good enough to use? Maybe Cryptocat et al could implement it, rather than creating their own.


SILC has it own set of problems though: https://we.riseup.net/riseup+tech/problems-with-silc


That is extremely helpful, thank you very much.


Seems very insecure - the keys are sent over the same channel as the messages? Anybody who gets access to the server can log all keys and decrypt all messages passing through.


From a very cursory look at the source code, it seems like every user share their public keys and the room keys are encrypted with these keys. So looking at server logs don't give you the room keys.

The public keys are sent across the same channel, though, and I don't see any mechanism in place to prevent the server from replacing that public key with their own (man in the middle attack). Maybe I'm missing something.


What's more, if you can't vet who joins the channel, then you can still have eavesdroppers listening in. So it's really no more secure than IRC over SSL (in fact probably less so because at least with SSL, eavesdroppers would need either access to your channel or to the server. So PMs and private channels are secure. With this, everyone shares the same certs so even your PMs are at risk).

> I don't see any mechanism in place to prevent the server from replacing that public key with their own

I'm not sure that's possible without exchanging the cert via peer-to-peer. In which case, you've already solved the toughest bit of the chat protocol (the handshake and coordination across the clients) so you might as well go fully peer-to-peer and do away with the server entirely.


You can vet who joins the channel by denying unauthorized users the room key. Users who don't have the key cannot post messages to the room.

User authentication, so someone is not able to impersonate you, is on the todo list but it is assumed that the server is trusted and won't go swapping public keys on you. A chat system that doesn't trust the server would need an entirely different design. You need to trust the server to perform basic actions like broadcast your message to the other users in the room.


If that's the case, why go through all this hassle? Simply use IRC with SSL and you have exactly the same level of security. As long as you trust the server, you are fine.


I think there's still value in hiding the conversation from the server even if you must still trust the server to not behave maliciously. If some three-letter agency contacts the server operator asking for a back channel to listen in, he or she could respond that it's not possible without malicious intent towards a user:

http://www.macobserver.com/tmo/article/apples-imessage-encry...


Point taken, you're correct - 1.1 is bigger than 1.0, and if the choice is open, choosing the 1.1/semi secure option is definitely better.


>TODO: Disallow unicode usernames

Can anyone explain why this is necessary?


I think it's just to stop name spoofing using unicode characters. ie pretending to use a registered nick by using characters that look similar. As a non-unicode example: "Bob" looks like "B0b".

Personally though, I'd rather welcome that kind of abuse but not exclude other people from countries who don't use the Latin alphabet. As demonstrated above, it's impossible to automatically moderate username abuse entirely anyway - as you can just start using non-unicode characters or even punctuation such as periods after the username. And if the chat protocol is built in a secure way (which this is not), then there should be other mechanisms for ensuring that Bob is in fact "Bob" and not "B0b" nor "Bob."


hn is not your mother's refrigerator door.


On the contrary - http://showinghn.com/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: