0

I need to implement symmetric encryption to enable secure communication between one program running on a Windows machine (to be written in VB.Net) and an app running on an iOS device (to be written in Swift). I'd like to use a reasonably modern algorithm which is supported in both programming languages "out of the box" without having to import more code than necessary.

The use case is, information (mostly, text files) will be encrypted by one program (say, running on Windows) and uploaded to a server, where it will be stored, then later downloaded and then decrypted by the other program (running on iOS). The server doesn't need access to the content of the file, and having the information "encrypted at rest" on the server is the main goal, although having it encrypted during transit to/from the server is also beneficial. The Windows and the iOS devices themselves aren't considered to be targeted in this case.

What algorithm(s) are good choices as being modern, secure, and available in both Swift and Dot Net so that what's encrypted by one can be decrypted by the other?

2

AES-GCM (Advanced Encryption Standard in Galois/Counter Mode) is the go-to standard for secure symmetric encryption these days, and is very widely supported (some libraries might still call AES "Rijndael"; just stick to 128 bit blocks and 128, 192, or 256-bit keys and it should be compatible). You can use AES with other modes, such as CBC, but this opens you to additional risks such as padding oracle attacks and additionally requires using another primitive (such as a secure hash function) to provide integrity for the encrypted data (using a construction such as an HMAC). GCM (if used correctly) authenticates the data for you, which most ciphers and "modes of operation" do not. However, GCM is somewhat tricky to use safely; there are alternatives such as [X]ChaCha20-Poly1305 (the ChaCha20 stream cipher - or its XChaCha20 variant - with an authenticated encryption) that are preferred in some implementations.

HOWEVER, having said that, you should consider using a library that already implements the crypto for you and was written, reviewed, and tested by experts. Crypto newbies should not attempt to use cryptographic primitives (such as AES) directly unless they have no other choice (it's just way, way too easy to screw something up; even experienced crypto developers miss things and it sounds like you don't even know what to look out for). One such library is "libsodium", although even it might be a bit much for a raw beginner. It is written in C but does have lots of bindings for other languages (including .NET and Swift). It includes functions to do everything you need.

Of course, once you've got your crypto library (third-party or hand-rolled atop the primitives), you still have the question of where and how to store/transmit the key. It doesn't do any good to encrypt something if the other side can't decrypt it, and it also doesn't do any good to encrypt something if everybody can decrypt it (which is what you'll get if you try doing something like hard-coding the key in the app). Using a password (via a "key derivation function") is one option. Another is to transmit the key (through a secure channel, such as HTTPS) to the server, but then the encryption isn't truly end-to-end; the server has everything it needs to decrypt the data, and if the server is ever compromised then the attacker will be able to decrypt the users' data too.

End-to-end encryption is hard to do right. Even a relatively simple cryptosystem is a massive pile of things that are easy forget or mess up, and a simple mistake can mean it all falls apart. As a general rule, if any of the algorithms or considerations I mentioned in this post are things you haven't heard of before, you should probably do some more reading before you try to write this code. I've seen lots of developers - even at big, highly-exclusive software companies with huge amounts of institutional knowledge - try to write their own cryptosystem and screw it up, often in some way that completely breaks its security.

1
  • Thanks -- libsodium did what I needed, and I have the two programs decrypting each other's messages. Given the importance of getting the many many details exactly right, I'm surprised that the languages themselves don't go farther in the direction that libsodium and such have gone, to make it easy for the developer to get things right, with minimal opportunities to screw up. Ah well. As for the key, by the time a user has registered with the of the app, they've been authenticated enough to be trusted. Without registration, the app won't download anything. – ConfusionTowers Apr 1 '20 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.