I was randomly thinking a bit today about how to implement a secure, encrypted instant messaging system. One that could be so easy to use, that mere mortals wouldn't need to worry too much about public/private key pairs, and yet the system would be self-verifying and all very automatic.
The base concept I was thinking of would be that usernames on this system would be numeric, a bit like ICQ numbers. People apparently didn't mind being assigned some "random" number that they logged in with and gave out to friends. But, unlike ICQ numbers, the numeric IDs on this system would actually serve a purpose (instead of being simply the auto-incrementing primary key in ICQ's database).
Each user's client would generate an RSA public/private key pair, which is obviously the foundation for any sort of secure messaging platform. Then, you'd take the fingerprint of the public key (a short hexadecimal string, which could look for example like "45:2f:a5:d8:13:95:ba:03:51:c4:8d:ac:82:a8:4c:6a"), and you'd turn that into an integer number. Then you'd take, say, the first and last 5 digits of the number to create a 10 digit "screen name" number.
For the sake of continuing my description, let's pretend that the number came out to 567-8426-789. When setting up the chat client for the first time, it generates keys behind the scenes, and says "Your login number is 567-8426-789. You can give this out to your friends so they can add you to their buddy lists."
This idea stems from the general practice where, suppose you downloaded a Linux OS DVD, and you wanna verify the download so you look up the
sha256sum for it. You're not going to compare the two SHA-256 hashes character by character; you'll check that the first 5 or 6 digits are the same, and the last 5 or 6 too. If those are, you can reasonably assert that your copy of the DVD is the same as the intended one. The numeric login ID of this secure IM network would be similar.
By giving out your ID number to a friend, they're automatically verifying your identity, since your ID is based off your public key. If somebody was trying to impersonate you (with a completely different RSA key pair), they wouldn't likely end up with the same numeric ID so it wouldn't work.
Of course, the IM clients themselves would include features to do a more thorough verification of the friend you just added, like allowing you to see their full hexadecimal fingerprint, and also show a visual fingerprint to make it even easier to verify at a glance that your friend is who you expect them to be.
Anyway, this is just the basic idea I had. As far as syncing other devices to use the same account goes, it would probably need something like the old/current method Firefox Sync uses, i.e. needing to enter a "random" code from one device into the other so that your private key can be securely transferred between them without a third party in the middle being able to see. Alternately, the system would be federated (so you could host your own servers, like XMPP), and your local server may be trusted with an encrypted copy of your private key, encrypted using your log-in password. But these are all details to be figured out later.
Today I decided to look into how well XMPP gateways work. Here's how it went.
XMPP Gateways (or, alternately, Transports) are services for XMPP that let users sign on to other instant messaging networks (AIM, MSN, YMSG, etc.) through their XMPP account. So... you sign in to XMPP and the server signs you in to your other networks, and you can do all your chatting through just the one XMPP connection (Wikipedia has a nice diagram of this).
So I was wondering whether this would be a good solution for programming chatbots that work on many different IM networks. In Perl, the options for IM network connectivity aren't all that great at the moment; there is Net::OSCAR for AIM, Net::XMPP, and that's about it. Matt Austin and I were working on Net::IM::YMSG for Yahoo Messenger, but it's not that great yet (it can chat and accept add requests, but after accepting you don't see it online until the program restarts). For MSN Messenger, there's a dusty old MSN.pm module somewhere on the RiveScript forums that might still work but hasn't been updated in years.
I'm not very motivated to work more on Net::IM::YMSG because YMSG is dead to me. I created a new Yahoo ID recently, and made sure to opt-out of any directory listings, and it still gets add requests by spam bots on a regular basis. The ID is literally listed nowhere. I don't know how they find me. It is my opinion that nobody should take YMSG seriously anymore. I don't know anybody who uses it, so developing new code to use YMSG isn't worth my time.
With XMPP gateways though, one could just write an XMPP bot and let the gateways do all the work. Then you can have a bot sign on to AIM, Yahoo, MSN, ICQ, IRC, and even some obscure networks like MySpace IM, without needing to use native libraries for each protocol yourself. Sounds great, but I had some questions about how well gateways work (how many features they support per network, etc.)... so the best way to find out was to test it!
I installed the Openfire XMPP Server on my web server. Installation was surprisingly super easy. Basically all I had to do was this:
# apt-get install sun-java6-jre # dpkg -i openfire_3.7.1_all.deb
This installed it and automatically started it, and then I went to the admin panel port on my server to set it up. I didn't have to touch any config files or anything; everything was done through the web panel and was dead simple. I set up a Jabber user @kirsle.net and then I went out in search of a gateway plugin.
I found Kraken to fill the role. Installing this plugin was super ridiculously simple too, I just copied kraken.jar to
/usr/share/openfire/plugins and Openfire automatically saw it and extracted it and a new "Gateways" tab appeared in the web panel. Black magic. I later discovered that I could've just uploaded kraken.jar to a file upload field on the Plugins page on the web panel, too. This is, by far, the easiest server software for Linux that I've ever seen. I can't believe Openfire is free and open source.
So after setting the gateways up for the protocols that I care about, here is what I found:
For simple chatbots that only need to communicate over IM, XMPP gateways should work out fine. But if you have a native way to connect to a particular network, that method would most surely be preferred.
The reason I like the @aim.kirsle.net etc. suffixes on gateway usernames is because it would make it easier for a chatbot to distinguish unique users across multiple networks. In my Aires bot (which supports AIM and YMSG, through Net::IM::YMSG), and in all my older bots from years gone by, the protocol-facing code would format a user's name like "AIM-kirsle" or "YMSG-kirsle" before passing it to the main bot code. This way I could make an AIM user an admin for my bot, without any confusion about overlapping Yahoo IDs of the same name. Since the XMPP transports make a unique subdomain for each network, this can be used instead.
In conclusion, I think it will be worth it to add XMPP support to my Aires bot so that transports can be used for people who want them. Native support for a network is always preferred, but with transports you can easily put your bot on a lot more networks with very little effort.