Einführung in die Verschlüsselung und Entschlüsselung in Laravel

巴扎黑
Freigeben: 2023-03-16 11:32:02
Original
1798 Leute haben es durchsucht

Dieser Artikel führt Sie hauptsächlich in die Implementierungsmethoden zum Verschlüsseln und Entschlüsseln in Laravel ein. Er bietet einen gewissen Referenz-Lernwert für alle, die ihn beim Lernen oder Arbeiten benötigen gemeinsam lernen.

Vorwort

Der Verschlüsselungsmechanismus von Laravel verwendet OpenSSL, um AES-256- und AES-128-Verschlüsselung bereitzustellen. In diesem Artikel wird die Verschlüsselung im Detail vorgestellt Laravel Und die Implementierung von Decrypt wird zum Nachschlagen und Studieren für alle geteilt. Ich werde im Folgenden nicht viel sagen, werfen wir einen Blick auf die detaillierte Einführung.

1. So verwenden Sie

Generieren Sie zunächst den geheimen Schlüssel. Sie müssen APP_KEY im .env-Verzeichnis bereitstellen. Wenn dieser nicht verfügbar ist, können Sie ihn mit dem Befehl php artisan key:generate generieren oder selbst festlegen. Das generierte Beispiel sollte wie folgt aussehen:


APP_KEY=base64:5BM1BXGOBrGeeqJMAWJZSzyzh5yPcCGOcOGPtUij65g=
Nach dem Login kopieren

Konfigurieren Sie den Verschlüsselungsschlüssel und den Verschlüsselungsalgorithmus in der Datei und konfigurieren Sie sie im Verzeichnis config/app.php


$ 'key' => env('APP_KEY'),
 
  'cipher' => 'AES-256-CBC',
Nach dem Login kopieren

Die Verwendungsmethode ist bereits in Laravel verfügbar, daher werde ich hier nicht zu sehr ins Detail gehen. Die beiden wichtigsten verwendeten Methoden sind Verschlüsselung durch Verschlüsseln und Entschlüsseln durch Entschlüsseln

2. Finden Sie verschlüsselte und entschlüsselte Dateien

Der Speicherort von Die Implementierungsmethode besteht darin, dass zwei Dateien im Verzeichnis seller/illuminate/encryption/ gefunden werden, eine ist EncryptionServiceProvider und die andere ist Encrypter

3 Analysieren Sie die EncryptionServiceProvider-Datei


 public function register()
 {
  $this->app->singleton('encrypter', function ($app) {
   $config = $app->make('config')->get('app'); //从config/app.php里拿到配置文件

   if (Str::startsWith($key = $config['key'], 'base64:')) { //分析配置文件里的key里面有没有带'base64'
    $key = base64_decode(substr($key, 7)); //如果有的话,把key前面的base64:给取消,并且解析出原来的字符串
   }

   return new Encrypter($key, $config['cipher']); //实例化Encrypte类,注入到框架里
  });
 }
Nach dem Login kopieren

Diese Datei hat nicht viel, aber daraus können wir ersehen, dass wir den Schlüssel tatsächlich direkt in die Konfigurationsdatei schreiben können. und es gibt kein vorheriges Es kann auch mit base64 analysiert werden. Dies entspricht dem Einsparen einiger Schritte

Außerdem müssen Sie beim Instanziieren der Klasse den Schlüssel und die Verschlüsselungsmethode übergeben

4 die Encrypter-Datei

1. Analysieren Sie __construct und führen Sie die obige Methode von


 public function __construct($key, $cipher = 'AES-128-CBC')
 {
  $key = (string) $key; //把key转换为字符串

  if (static::supported($key, $cipher)) { //调用一个自定义的方法,用来判断加密方式和要求的key长度是否一样
   $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.');
  }
 }
Nach dem Login kopieren

aus Instanziierung wird hauptsächlich verwendet, um festzustellen, ob die Verschlüsselungsmethode und die Länge des übertragenen Schlüssels gleich sind, da verschiedene Verschlüsselungsmethoden auch die Länge des entsprechenden Schlüssels erfordern. Insbesondere kann die Länge des Schlüssels sein, der für jede Verschlüsselungsmethode erforderlich ist gefunden im entsprechenden Dokument


 public static function supported($key, $cipher)
 {
  $length = mb_strlen($key, '8bit'); //判断key的字符的长度,按照8bit位的方式计算字符长度

  return ($cipher === 'AES-128-CBC' && $length === 16) ||
    ($cipher === 'AES-256-CBC' && $length === 32); //编码格式为AES128的要求字符长度为16。编码格式为AES256的要求字符长度为32位
 }
Nach dem Login kopieren

Die obige Methode zeigt einen strengen Punkt, bei dem die mb_strlen-Methode verwendet wird und die Berechnungslänge auf der Grundlage von 8 Bits berechnet werden muss. Dies hat den Vorteil, dass die Länge der Berechnung unabhängig vom Betriebssystem gleich ist.

Durch die Berücksichtigung der Bedingungen verschiedener Betriebssysteme treten keine Verschlüsselungsprobleme auf.

2. Analysieren Sie die Verschlüsselungsmethode


 public function encrypt($value, $serialize = true)
 {
  $iv = random_bytes(16); //生成一个16位的随机字符串
  
  
  // 使用openssl_encrypt把数据生成一个加密的数据
  // 1、判断需要不需要生成一个可存储表示的值,这样做是为了不管你的数据是数组还是字符串都能给你转成一个字符串,不至于在判断你传过来的数据是数组还是字符串了。
  // 2、使用openssl_encrypt。第一个参数是传入数据,第二个参数是传入加密方式,目前使用AES-256-CBC的加密方式,第三个参数是,返回加密后的原始数据,还是把加密的数据在经过一次base64的编码,0的话表示base64位数据。第四个参数是项量,这个参数传入随机数,是为了在加密数据的时候每次的加密数据都不一样。
  $value = \openssl_encrypt(
   $serialize ? serialize($value) : $value,
   $this->cipher, $this->key, 0, $iv
  ); //使用AES256加密内容

  if ($value === false) {
   throw new EncryptException('Could not encrypt the data.');
  }

  $mac = $this->hash($iv = base64_encode($iv), $value); //生成一个签名,用来保证内容参数没有被更改

  $json = json_encode(compact('iv', 'value', 'mac')); //把随机码,加密内容,已经签名,组成数组,并转成json格式

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

  return base64_encode($json); //把json格式转换为base64位,用于传输
 }
Nach dem Login kopieren

Eine benutzerdefinierte Methode hash() wird oben verwendet, wir können die Implementierung sehen der folgenden Methode.


 protected function hash($iv, $value)
 {
  // 生成签名
  // 1、把随机值转为base64
  // 2、使用hash_hmac生成sha256的加密值,用来验证参数是否更改。第一个参数表示加密方式,目前是使用sha256,第二个是用随机值连上加密过后的内容进行,第三个参数是上步使用的key。生成签名。
  return hash_hmac('sha256', $iv.$value, $this->key); /根据随机值和内容,生成一个sha256的签名
 }
Nach dem Login kopieren

Die obige Verschlüsselung ist in drei Hauptschritte unterteilt

1. Zufallscode generieren

2. Verschlüsselten Inhalt generieren

3. Signatur generieren

Das Framework verwendet eine elegante Methode, bei der Serialisierung zum Generieren eines Werts verwendet wird. Die Eleganz dieser Methode besteht darin, dass sie keine Rolle spielt Was Sie haben Unabhängig davon, ob der Inhalt ein Array oder eine Zeichenfolge ist, kann er in eine Zeichenfolge konvertiert werden. Was ist der Unterschied zwischen der Verwendung von Serialize und der Verwendung von json_encode? Der größte Vorteil besteht meiner Meinung nach darin, dass die Serialisierung relativ schneller erfolgt, wenn der Inhalt, den Sie verschlüsseln möchten, relativ groß ist.

Eine weitere Sache ist, dass das Framework beim Verschlüsseln eine zufällige Zeichenfolge verwendet. Warum eine zufällige Zeichenfolge verwenden? Da eine zufällige Zeichenfolge verwendet wird, ist der verschlüsselte Inhalt jedes Mal anders, um zu verhindern, dass andere ihn erraten.

3. Analyse der Entschlüsselungsmethode

Das Entschlüsseln von Daten ist nicht nur der komplizierteste Teil, sondern auch das Entschlüsseln der Daten Stellen Sie die Integrität der Daten sicher Die validPayload-Methode wird nicht erwähnt. Vergleichen Sie einfach und grundlegend. Der Schwerpunkt liegt auf der ValidMac-Überprüfung, um sicherzustellen, dass die Daten nicht manipuliert werden. Dies ist das Wichtigste >calculateMac-Methode besteht darin, basierend auf den Originaldaten eine Signatur mit einem Zufallswert zu generieren und diese Signatur dann zu verwenden, um erneut eine Signatur zu generieren


public function decrypt($payload, $unserialize = true)
 {
  $payload = $this->getJsonPayload($payload); //把加密后的字符串转换出成数组。

  $iv = base64_decode($payload['iv']); //把随机字符串进行base64解密出来

  $decrypted = \openssl_decrypt( //解密数据
   $payload['value'], $this->cipher, $this->key, 0, $iv
  );

  if ($decrypted === false) {
   throw new DecryptException('Could not decrypt the data.');
  }

  return $unserialize ? unserialize($decrypted) : $decrypted; //把数据转换为原始数据
 }
Nach dem Login kopieren

Die obige Entschlüsselung ist in drei Hauptschritte unterteilt


1. Bestimmen Sie die Integrität der Daten
 protected function getJsonPayload($payload)
 {
  $payload = json_decode(base64_decode($payload), true); //把数据转换为原来的数组形式

  if (! $this->validPayload($payload)) { //验证是不是数组以及数组里有没有随机字符串,加密后的内容,签名
   throw new DecryptException('The payload is invalid.');
  }

  if (! $this->validMac($payload)) { //验证数据是否被篡改
   throw new DecryptException('The MAC is invalid.');
  }

  return $payload;
 }
Nach dem Login kopieren

2. Bestimmen Sie die Konsistenz der Daten


3. Entschlüsseln Sie den Dateninhalt.
 protected function validMac(array $payload)
 {
  $calculated = $this->calculateMac($payload, $bytes = random_bytes(16)); //拿数据和随机值生成一个签名

  return hash_equals( //比对上一步生成的签名和下面生成的签名的hash是否一样。
   hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated //根据原始数据里的签名在新生成一个签名
  );
 }
Nach dem Login kopieren

Diese Verifizierungssignatur hat etwas Seltsames. Sie ist nicht dasselbe wie unsere übliche Signaturverifizierung. Normalerweise überprüfen wir Signaturen, indem wir die Originaldaten und Zufallswerte verwenden, um eine Signatur zu generieren, und vergleichen dann die generierte Signatur mit der Signatur der Originaldaten, um festzustellen, ob sie manipuliert wurde.

Aber es gibt noch ein weiteres Framework, das er verwendet, um eine Signatur anhand der Originaldaten und Zufallswerte zu generieren und diese Signatur dann zum Generieren einer Signatur zu verwenden. Der Vergleich besteht auch darin, die Signatur in den Originaldaten zu verwenden Erstellen Sie eine Signatur und vergleichen Sie sie. Ich kann nicht verstehen, warum es noch ein paar Schritte braucht.

Während der Verschlüsselung haben wir die Originaldaten mit Serialize konvertiert, daher müssen wir auch unserialize verwenden, um die Daten entsprechend zurück zu konvertieren.

Hinweis

  • Der für die Verschlüsselung verwendete zufällige Elementwert in openssl_encrypt ist der ursprüngliche Binärwert der Daten Der mit openssl_decrypt entschlüsselte Wert ist eine zufällige Zeichenfolge, nachdem Base64-Bits verwendet wurden.

  • Anstatt beim Generieren von Signaturen zum Vergleich während der Entschlüsselung die Originalsignatur zu verwenden und dann eine Signatur zum Vergleich basierend auf dem Inhalt der Originaldaten neu zu generieren, verwenden wir die Originalsignatur als Grundlage Um eine Signatur zu generieren, nehmen Sie dann die basierend auf den Originaldaten generierte Signatur und verwenden Sie diese neu generierte Signatur, um eine Signatur neu zu generieren. Dann vergleichen Sie.

  • AES256 sind verschlüsselte Daten, die später rückwärts entschlüsselt werden können. SHA256 generiert eine Signatur. Dieser Vorgang ist irreversibel und dient der Überprüfung der Integrität der Daten.

Das obige ist der detaillierte Inhalt vonEinführung in die Verschlüsselung und Entschlüsselung in Laravel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage