Once you have the infrastructure for secure chatting between clients, expanding it to handle more than just text is a matter of encoding.
And so I’ve extended the client to allow sending and receiving photographs. Securely.
A new version has been pushed to the master branch of GitHub.
The interesting part about all this is learning the limitations of encryption using an RSA public/private key architecture.
The upside: unless the encryption key is generated on your device and shared using a secure mechanism (such as public/private key architecture), your protocol is not secure. Sure, your specifications may claim that the server-generated encryption key used by the clients is not stored on the server after it is generated–but we only have your promise.
RSA public/private key encryption, however, is computationally expensive. Even on Android, where the BigInteger implementation has been seriously optimized over my first pass attempt at building my own BigInteger code, encrypting and decrypting an image can be quite costly. It’s why, I suspect, most commercial applications use a symmetric encryption mechanism–because most symmetric encryption systems are significantly faster (as they involve bit-wise operations rather than calculating modulus products on large integers.
Which is why I’ll be focusing my attention on the iOS implementation of BigInteger.
But even on Android, decrypting a message using a 1024 bit RSA key can be acceptably fast enough, especially if encryption security is more important to you than efficiency.
In practice I can see using something like Diffie-Hellman to mediate exchanges between two devices. Nothing behind the mathematics of that protocol require the protocol to be completed in one session; there is no reason why the server couldn’t store the first part of the exchange (the value A = ga mod p) on the server, so that later another client B couldn’t then complete the exchange. It implies each device stores the shared secret of all the devices it is communicating with–but with today’s modern devices, storing a thousand shared secrets doesn’t represent a lot of memory.
It may also be possible to use a variation of Diffie-Hellman in conjunction with a symmetric encryption algorithm (perhaps by using the shared secret as a key to such an encryption scheme).