This article mainly introduces to you about Laravel in encrypt and decrypt implementation method, the text through the sample code introduced in very detailed, to everyone's study or work has a certain reference learning value, the need for friends below with small to learn together.
Objective
Laravel encryption mechanism using OpenSSL to provide AES-256 and AES-128 encryption, this article will be introduced in detail about Laravel encrypt and decrypt implementation, sharing out for everyone to reference the study, the following words do not say, come together to see the detailed introduction bar.
1. How to use
The first is to generate the secret key. You need to provide app_key in the. env directory, which can be generated by command if not, php artisan key:generate
or set yourself. The post-build example should look like this
app_key=base64:5bm1bxgobrgeeqjmawjzszyzh5ypccgocogptuij65g=
Configure encryption key and encryption algorithm in file, config in config/app.php directory
$ ' key ' = env (' App_key '), ' cipher ' = ' AES-256-CBC ',
Using the method, there is already a way to use in the Laravel, here is not too much to say. The main use of the two methods, one is encrypt encryption, one is the decryption of decrypt
2. Find encrypted and decrypted files
The implementation method is located in the vendor/illuminate/encryption/directory found two files, one is Encryptionserviceprovider and the other is Encrypter
3. Analyzing Encryptionserviceprovider Files
Public Function Register () { $this->app->singleton (' Encrypter ', function ($app) { $config = $app Make (' config ')->get (' app '); Get the config file from the config/app.php if (str::startswith ($key = $config [' key '], ' base64: ')) {///The key inside the profiling configuration file contains ' base64 ' $key = Base64_decode (substr ($key, 7));//If any, remove the base64 in front of the key: Cancel and parse the original string } return new Encrypter ($key, $config [' cipher ']); Instantiate the Encrypte class, inject into the frame }); }
This file does not have a lot of things, but through this we can see, in fact, in the configuration file, we can directly write key, and the front without Base64 is also can parse. Equivalent to a few steps of the province
In addition, when you instantiate a class, you need to pass in the key and the encryption method
4. Analyzing encrypter Files
1. Analyze __construct, execute before instantiation
Public function __construct ($key, $cipher = ' AES-128-CBC ') { $key = (string) $key;//Convert key to String if (Static::suppo RTed ($key, $cipher)) {//Call a custom method to determine if the encryption method and the required key length are the same $this->key = $key; $this->cipher = $cipher; } else { throw new RuntimeException (' The only supported ciphers is AES-128-CBC and AES-256-CBC with the correct key Len Gths. '); } }
The above method is mainly used to determine whether the encryption method and the length of the key passed is the same, because different encryption methods, the required length of the corresponding key is also required, each encryption method requires key length can find the corresponding document
public static function supported ($key, $cipher) { $length = Mb_strlen ($key, ' 8bit ');//Determine the length of the key's character and calculate the character length in 8bit bits return ($cipher = = = ' AES-128-CBC ' && $length = = =) | | ($cipher = = = ' AES-256-CBC ' && $length = = = 32); The encoding format for AES128 requires a character length of 16. The encoding format for AES256 requires a character length of 32 bits}
The above method shows a rigorous place, using the Mb_strlen method, and requires that the calculation length is calculated according to the 8bit bit. The advantage is that the length of the calculation is the same regardless of the operating system.
With this consideration of the different operating systems, there will be no problem with encryption.
2. Analyzing the Encrypt method
Public Function encrypt ($value, $serialize = True) {$iv = Random_bytes (16);//Generate a 16-bit random string//use Openssl_encrypt to generate an encrypted data//1, it is necessary to determine the need not to generate a stored representation of the value, so that whether your data is an array or a string can be converted to a string for you, Don't judge whether the data you passed is an array or a string. 2, use Openssl_encrypt. The first parameter is the incoming data, the second parameter is the incoming encryption method, the current use of AES-256-CBC encryption, the third parameter is to return the original encrypted data, or the encrypted data after a base64 encoding, 0 words to represent base64 bit data. The fourth parameter is the item amount, which is passed to the random number in order to encrypt the data each time the encrypted data is different. $value = \openssl_encrypt ($serialize? Serialize ($value): $value, $this->cipher, $this->key, 0, $iv); Use AES256 to encrypt the content if ($value = = = False) {throw new Encryptexception (' Could not encrypt the data. '); } $mac = $this->hash ($iv = Base64_encode ($IV), $value); Generate a signature to ensure that the content parameters have not been changed $json = Json_encode (Compact (' IV ', ' value ', ' mac '); Put random code, encrypt content, have signed, form an array, and turn to JSON format if (! is_string ($json)) {throw new Encryptexception (' Could not encrypt the data. '); } return Base64_encode ($json); Convert JSON format to base64 bit for transfer}
The above uses a custom method hash (), we can see the implementation of the method.
protected function hash ($IV, $value) { //Generate signature //1, convert random value to base64 //2, use HASH_HMAC to generate sha256 encrypted value, to verify that the parameter is changed. The first parameter represents the encryption method, is currently using SHA256, the second is a random value connected to the content after the encryption, the third parameter is the key used in the step. Generate a signature. return Hash_hmac (' sha256 ', $iv. $value, $this->key);/Generate a sha256 signature based on random values and content}
The above encryption is a total of three major strides
1. Generate Random Code
2. Generate Encrypted Content
3. Generate signature
The framework uses an elegant approach, using serialize to generate a value, which is elegant, that is, whether your content is an array or a string, it can be converted to a string. And the difference between using serialize and using Json_encode, I think the biggest advantage is that you want to encrypt the content is relatively large, serialize relative to the faster.
Another place is that the framework uses a random string when it is encrypted. Why use random strings, because the use of random strings, so that each time the contents of the encryption is different, to prevent others to guess.
3. Analyzing the Decrypt method
Decryption of data, can be said to be the most complex piece, not only to decrypt the data, but also to ensure the integrity of the data, as well as data anti-tampering
Public function Decrypt ($payload, $unserialize = True) { $payload = $this->getjsonpayload ($payload); Converts the encrypted string to an array. $iv = Base64_decode ($payload [' IV ']),//base64 the random string to decrypt it $decrypted = \openssl_decrypt (//Decrypt data $ payload[' value '], $this->cipher, $this->key, 0, $iv ); if ($decrypted = = = False) { throw new decryptexception (' Could not decrypt the data. '); } Return $unserialize? Unserialize ($decrypted): $decrypted; Convert data to raw data}
Getjsonpayload method
protected function Getjsonpayload ($payload) { $payload = Json_decode (Base64_decode ($payload), true); Convert the data to the original array form if (! $this->validpayload ($payload)) {//validation is not an array and there are no random strings in the array, encrypted content, signature throw new Decryptexception (' The payload is invalid. '); } if (! $this->validmac ($payload)) {//Verify data is tampered with throw new Decryptexception (' The MAC is invalid. '); } return $payload; }
Validpayload method does not say, relatively simple and basic, the focus is to say Validmac verify this piece, to ensure that the data is not tampered with, this is the most important
protected function Validmac (array $payload) { $calculated = $this->calculatemac ($payload, $bytes = Random_bytes ( 16)); Generate a signature with data and random values return hash_equals (//is the same as the hash of the signature generated in the previous step). Hash_hmac (' sha256 ', $payload [' Mac '], $bytes, true), $calculated//According to the signature in the original data in a new signature ); }
The Calculatemac method is to generate a signature based on the original data and random values, and then use that signature to generate a signature again
protected function Calculatemac ($payload, $bytes) { return Hash_hmac ( ' sha256 ', $this->hash ($payload [' IV ') ], $payload [' value ']), $bytes, true ); }
The above decryption is a three-step
1, judge the integrity of the data
2, judge the consistency of the data
3. Decrypt the contents of the data.
This verification signature has a strange place, and he is not the same as we usually verify the signature. We normally verify signatures by generating a signature with raw data and random values, and then determining whether there has been tampering with the generated signature and the signature of the original data.
And the framework is one more, he used, after the original data and random values to generate a signature, and then take the signature generated a signature, rather than the original data in the signature is generated by a signature, and then the comparison. At the moment, I can't figure out why we need a few more steps.
At the time of encryption, we converted the raw data using serialize, so we also need to use Unserialize to convert the data back.
Attention
The value of the random item in the Openssl_encrypt used when encrypting is the raw data raw this binary value, using the Openssl_decrypt decrypted values is the random string that is used after the base64 bit.
When decrypting a signature comparison, instead of using the original signature, and then comparing it with the original data's contents, regenerate the signature, instead, generate a signature based on the original signature, and then regenerate the signature with the newly generated signature, using the signature generated from the original data. And then the comparison is made.
AES256 is encrypted data, which can be reversed to decrypt the data later. While SHA256 is a signature generation, this process is irreversible and is intended to verify the integrity of the data.
Summarize