Tutorial ========= Hello! If you're reading this file, it's because you want to add encryption to one of your PHP projects. My job, as the person writing this documentation, is to help you make sure you're doing the right thing and then show you how to use this library to do it. To help me help you, please read the documentation *carefully* and *deliberately*. A Word of Caution ------------------ Encryption is not magic dust you can sprinkle on a system to make it more secure. The way encryption is integrated into a system's design needs to be carefully thought out. Sometimes, encryption is the wrong thing to use. Other times, encryption needs to be used in a very specific way in order for it to work as intended. Even if you are sure of what you are doing, we strongly recommend seeking advice from an expert. The first step is to think about your application's threat model. Ask yourself the following questions. Who will want to attack my application, and what will they get out of it? Are they trying to steal some information? Trying to alter or destroy some information? Or just trying to make the system go down so people can't access it? Then ask yourself how encryption can help combat those threats. If you're going to add encryption to your application, you should have a very clear idea of exactly which kinds of attacks it's helping to secure your application against. Once you have your threat model, think about what kinds of attacks it *does not* cover, and whether or not you should improve your threat model to include those attacks. **This isn't for storing user login passwords:** The most common use of cryptography in web applications is to protect the users' login passwords. If you're trying to use this library to "encrypt" your users' passwords, you're in the wrong place. Passwords shouldn't be *encrypted*, they should be *hashed* with a slow computation-heavy function that makes password guessing attacks more expensive. See [How to Safely Store Your Users' Passwords in 2016](https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016). **This isn't for encrypting network communication:** Likewise, if you're trying to encrypt messages sent between two parties over the Internet, you don't want to be using this library. For that, set up a TLS connection between the two points, or, if it's a chat app, use the [Signal Protocol](https://whispersystems.org/blog/advanced-ratcheting/). What this library provides is symmetric encryption for "data at rest." This means it is not suitable for use in building protocols where "data is in motion" (i.e. moving over a network) except in limited set of cases. Getting the Code ----------------- There are several different ways to obtain this library's code and to add it to your project. Even if you've already cloned the code from GitHub, you should take steps to verify the cryptographic signatures to make sure the code you got was not intercepted and modified by an attacker. Please head over to the [**Installing and Verifying**](InstallingAndVerifying.md) documentation to get the code, and then come back here to continue the tutorial. Using the Library ------------------ I'm going to assume you know what symmetric encryption is, and the difference between symmetric and asymmetric encryption. If you don't, I recommend taking [Dan Boneh's Cryptography I course](https://www.coursera.org/learn/crypto/) on Coursera. To give you a quick introduction to the library, I'm going to explain how it would be used in two sterotypical scenarios. Hopefully, one of these sterotypes is close enough to what you want to do that you'll be able to figure out what needs to be different on your own. ### Formal Documentation While this tutorial should get you up and running fast, it's important to understand how this library behaves. Please make sure to read the formal documentation of all of the functions you're using, since there are some important security warnings there. The following classes are available for you to use: - [Crypto](classes/Crypto.md): Encrypting and decrypting strings. - [File](classes/File.md): Encrypting and decrypting files. - [Key](classes/Key.md): Represents a secret encryption key. - [KeyProtectedByPassword](classes/KeyProtectedByPassword.md): Represents a secret encryption key that needs to be "unlocked" by a password before it can be used. ### Scenario #1: Keep data secret from the database administrator In this scenario, our threat model is as follows. Alice is a server administrator responsible for managing a trusted web server. Eve is a database administrator responsible for managing a database server. Dave is a web developer working on code that will eventually run on the trusted web server. Let's say Alice and Dave trust each other, and Alice is going to host Dave's application on her server. But both Alice and Dave don't trust Eve. They know Eve is a good database administrator, but she might have incentive to steal the data from the database. They want to keep some of the web application's data secret from Eve. In order to do that, Alice will use the included `generate-defuse-key` script which generates a random encryption key and prints it to standard output: ```sh $ composer require defuse/php-encryption $ vendor/bin/generate-defuse-key ``` Alice will run this script once and save the output to a configuration file, say in `/etc/daveapp-secret-key.txt` and set the file permissions so that only the user that the website PHP scripts run as can access it. Dave will write his code to load the key from the configuration file: ```php saveToAsciiSafeString(); // ... save $protected_key_encoded into the user's account record } ``` Then, when the user logs in, Dave's code will load the protected key from the user's account record, unlock it to get a `Key` object, and save the `Key` object somewhere safe (like temporary memory-backed session storage). Note that wherever Dave's code saves the key, it must be destroyed once the user logs out, or else the attacker might be able to find users' keys even if they were never logged in during the attack. ```php unlockKey($password); $user_key_encoded = $user_key->saveToAsciiSafeString(); // ... save $user_key_encoded in the session ``` ```php