Examples of encrypt and decrypt implementation methods in Laravel sharing

Source: Internet
Author: User
Tags decrypt
This paper mainly introduces the implementation of encrypt and decrypt in Laravel, the article introduces the example code in very detailed, to everyone's study or work has a certain reference learning value, the need for friends below with the small series 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 if not, can be generated by command PHP artisan key:generate, or you can set it 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 configuration file from config/app.php

    if (Str::startsWith($key = $config['key'],'base64:')) {//Analyze whether there is'base64' in the key in the configuration file
     $key = base64_decode(substr($key, 7)); //If there is any, cancel the base64: in front of the key, and parse the original string
    }

    return new Encrypter($key, $config['cipher']); //Instantiate the Encrypte class and inject it into the framework
   });
  }


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::supported($key, $cipher)) {//Call a custom method to determine whether the encryption method is the same as the required key length
    $this->key = $key;
    $this->cipher = $cipher;
   } else {
    throw new RuntimeException('The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths.');
   }
  }


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'); //Judging the length of the key character, and calculating the character length according to 8bit

   return ($cipher ==='AES-128-CBC' && $length === 16) ||
     ($cipher ==='AES-256-CBC' && $length === 32); //The required character length for encoding format of AES128 is 16. The encoding format is AES256, the required character length is 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 from the data
  // 1. It is judged that there is no need to generate a value that can be stored. This is to convert your data into a string regardless of whether your data is an array or a string, so as not to judge that the data you pass is an array Still a string.
  // 2. Use openssl_encrypt. The first parameter is the incoming data, the second parameter is the incoming encryption method, currently the AES-256-CBC encryption method is used, and the third parameter is whether to return the encrypted original data or to pass the encrypted data Once base64 encoding, 0 means base64 data. The fourth parameter is the item amount, this parameter is passed in a random number, so that the encrypted data is different every time when the data is encrypted.
  $value = \openssl_encrypt(
   $serialize? serialize($value): $value,
   $this->cipher, $this->key, 0, $iv
  ); //Use AES256 to encrypt 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')); //The random code, encrypted content, signed, form an array, and convert it to json format

  if (! is_string($json)) {
   throw new EncryptException('Could not encrypt the data.');
  }

  return base64_encode($json); //Convert json format to base64 bits for transmission
 }


The above uses a custom method hash (), we can see the implementation of the method.





protected function hash($iv, $value)
  {
   // Generate signature
   // 1. Convert the random value to base64
   // 2. Use hash_hmac to generate the sha256 encrypted value to verify whether the parameter has changed. The first parameter indicates the encryption method, currently sha256 is used, the second is to connect the encrypted content with a random value, and the third parameter is the key used in the previous step. Generate a signature.
   return hash_hmac('sha256', $iv.$value, $this->key); /According to the random value and content, generate a sha256 signature
  }


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); //Convert the encrypted string into an array.

   $iv = base64_decode($payload['iv']); //decrypt the random string to base64

   $decrypted = \openssl_decrypt( //Decrypted 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 original 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)) {//Verify whether the array and whether there is a random string in the array, the encrypted content, and the signature
    throw new DecryptException('The payload is invalid.');
   }

   if (! $this->validMac($payload)) {//Verify whether the data has been 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)); //Take data and random values to generate a signature

   return hash_equals( //Compare the hash of the signature generated in the previous step with the signature generated below.
    hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated //A new signature is generated based on the signature in the original data
   );
  }


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.

Alibaba Cloud Hot Products

Elastic Compute Service (ECS) Dedicated Host (DDH) ApsaraDB RDS for MySQL (RDS) ApsaraDB for PolarDB(PolarDB) AnalyticDB for PostgreSQL (ADB for PG)
AnalyticDB for MySQL(ADB for MySQL) Data Transmission Service (DTS) Server Load Balancer (SLB) Global Accelerator (GA) Cloud Enterprise Network (CEN)
Object Storage Service (OSS) Content Delivery Network (CDN) Short Message Service (SMS) Container Service for Kubernetes (ACK) Data Lake Analytics (DLA)

ApsaraDB for Redis (Redis)

ApsaraDB for MongoDB (MongoDB) NAT Gateway VPN Gateway Cloud Firewall
Anti-DDoS Web Application Firewall (WAF) Log Service DataWorks MaxCompute
Elastic MapReduce (EMR) Elasticsearch

Alibaba Cloud Free Trail

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.