In my [last post](https://medium.com/@bob_parks1/how-not-to-encrypt-a-file-courtesy-of-microsoft-bfadf2b0273d) I was clutching my pearls over a 13 year old MSDN article that had the gall to be written by somebody not familiar with the proper usage of cryptographic initialization vectors. Some of my fans were nice enough to point out that in all of my histrionic ranting and raving I forgot to say anything useful, like how you’re _actually_ supposed to encrypt a file.\n\nSo without further ado, here is how you encrypt and decrypt a file:\n\n$ gpg -c --cipher-algo AES128 \\[file\\] # Encrypt \n$ gpg -d \\[file\\].gpg # Decrypt\n\nAnticlimactic, right? It doesn’t even mention IVs, but that’s kind of the point. A tutorial about file encryption that includes manual handing of IVs is kind of like a tutorial about setting up a web server that includes reimplementing TCP. There’s literally no benefit to doing it and you’re almost guaranteed to do it wrong. It’s the difference between _encrypting a file_ and _implementing file encryption_. The first is a common task for a programmer and the second shouldn’t be attempted by a non-crypto-expert. Microsoft should know better than to conflate the two, especially in a tutorial intended for a lay audience.\n\n#### GPG?\n\nThis post isn’t supposed to be a tutorial about GPG, but if anybody actually wants to take my advice, please check out [the documentation](https://www.gnupg.org/gph/en/manual/x110.html). And if you’re looking to do file encryption in \\[target [programming](https://hackernoon.com/tagged/programming) language\\], just do the equivalent operations with an OpenPGP implementation in that language.\n\n#### Wow So PGP is Infallible?\n\nOh god no. It has many flaws, the biggest of which is probably the awful key distribution. It just happens to have a decent implementation of file encryption that’s available on just about every platform and in just about every programming language. If you want to be thoroughly confused about this topic, here are [Matthew Green](https://blog.cryptographyengineering.com/2014/08/13/whats-matter-with-pgp/) and [Filippo Valsorda](https://arstechnica.co.uk/security/2016/12/op-ed-im-giving-up-on-pgp/) shitting all over PGP.\n\n#### Hey, I Came Here For the Crypto Details!\n\nAlright so now that we’re all clear that when you want to encrypt a file you should just use a mainstream, high-level crypto library and not touch the primitives yourself, here is a basic way to implement file encryption that isn’t completely terrible:\n\n1. Select a secure, modern block cipher. I’d stick with AES128 unless you’ve got a really compelling reason to use something else. You can use AES256 if you want but realistically it’s not going to increase [security](https://hackernoon.com/tagged/security). Your password will have nowhere near 128 bits of entropy so it’s going to be by far the weakest link in this chain.\n2. Obtain a cryptographically secure random value to use as an initialization vector. (hint: use [/dev/urandom](https://security.stackexchange.com/a/3939))\n3. Obtain a high entropy key. In this case I’d say select a strong password (another topic entirely), then run it through [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) for [key stretching](https://en.wikipedia.org/wiki/Key_stretching). For simplicity you could use the IV as the salt.\n4. Using your block cipher, the key created from sending your password through bcrypt, and the IV generated from /dev/urandom, perform [cipher block chaining](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29) to encrypt your plaintext.\n5. Append the IV to the beginning of the ciphertext, then run that whole thing through [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code), preferably using SHA2 or SHA3. Note that we’re authenticating after encrypting, avoiding the [doom principle](https://moxie.org/blog/the-cryptographic-doom-principle/).\n6. Append the output of the HMAC to the IV and ciphertext, and output the result. So your output should be IV || CT || HMAC(IV || CT)\n\nThere you go, implementing file encryption in 6 easy steps. If you need a library that contains the primatives mentioned here, OpenSSL is a good option . If you want to decrypt, verify the HMAC by recomputing it from the IV || CT and compare with the given HMAC, then just undo the CBC encryption.\n\n#### That’s Cool…But Why Did We Do All That Stuff?\n\nThe randomized IV and cipher block chaining achieve [semantic security](https://en.wikipedia.org/wiki/Semantic_security) so that we don’t end up leaking information. The HMAC achieves [data integrity](https://en.wikipedia.org/wiki/Data_integrity) and [authentication](https://en.wikipedia.org/wiki/Authentication). Key stretching with bcrypt makes the key generated from your password slightly less terrible.\n\nIf you want to learn by playing around with these things programmatically (and you can tolerate a webapp with a UI designed by hackers) checkout [https://id0-rsa.pub/](https://id0-rsa.pub/).\n\n> [Hacker Noon](http://bit.ly/Hackernoon) is how hackers start their afternoons. We’re a part of the [@AMI](http://bit.ly/atAMIatAMI)family. We are now [accepting submissions](http://bit.ly/hackernoonsubmission) and happy to [discuss advertising & sponsorship](mailto:email@example.com) opportunities.\n\n> To learn more, [read our about page](https://goo.gl/4ofytp), [like/message us on Facebook](http://bit.ly/HackernoonFB), or simply, [tweet/DM @HackerNoon.](https://goo.gl/k7XYbx)\n\n> If you enjoyed this story, we recommend reading our [latest tech stories](http://bit.ly/hackernoonlatestt) and [trending tech stories](https://hackernoon.com/trending). Until next time, don’t take the realities of the world for granted!