Beispiel für die gemeinsame Nutzung von Implementierungsmethoden zum Verschlüsseln und Entschlüsseln in Laravel

小云云
Freigeben: 2023-03-19 12:34:01
Original
1759 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. Kommen Sie und lernen Sie gemeinsam.

Vorwort

Der Verschlüsselungsmechanismus von Laravel verwendet OpenSSL, um AES-256- und AES-128-Verschlüsselung bereitzustellen. In diesem Artikel wird die Implementierung der Verschlüsselung und Entschlüsselung in Laravel ausführlich vorgestellt und als Referenz bereitgestellt Im Folgenden gibt es nicht viel zu sagen, werfen wir einen Blick auf die ausführliche 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

Nutzungsmethoden: Es gibt bereits Verwendungsmethoden in Laravel, daher werde ich hier nicht zu sehr ins Detail gehen. Die beiden wichtigsten verwendeten Methoden sind Verschlüsselung und Entschlüsselung

2. Suchen Sie die Verschlüsselungs- und Entschlüsselungsdateien

Der Speicherort der Implementierungsmethode befindet sich in den Dateien „vendor/illuminate/Two“. wurden im Encryption/-Verzeichnis gefunden, einer ist EncryptionServiceProvider und der 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 enthält nicht viel, aber dadurch können wir Siehe Ja, tatsächlich können wir den Schlüssel direkt in die Konfigurationsdatei schreiben und er kann auch ohne Base64 analysiert werden. Dies entspricht der Einsparung einiger Schritte

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

4. Analysieren Sie die Encrypter-Datei

1. Analysieren Sie __construct und führen Sie

 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

vor der Instanziierung aus. Die obige Methode wird hauptsächlich verwendet, um festzustellen, ob die Verschlüsselungsmethode und die Länge des übergebenen Schlüssels gleich sind, da unterschiedliche Verschlüsselungsmethoden entsprechende Anforderungen erfordern Die Länge des Schlüssels ist ebenfalls erforderlich. Die Länge des für jede Verschlüsselungsmethode erforderlichen Schlüssels finden Sie 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 unter Verwendung der mb_strlen-Methode Die Länge muss gemäß Berechnet mit 8 Bits berechnet werden. 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

Oben wird eine benutzerdefinierte Methode hash() verwendet.

 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 mithilfe von Serialisierung ein Wert generiert wird. Die Eleganz dieser Methode besteht darin, dass sie in einen String umgewandelt werden kann, unabhängig davon, ob Ihr Inhalt ein Array oder ein Array ist Zeichenfolge. 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

Die Entschlüsselung der Daten muss nicht nur entschlüsselt werden, sondern auch die Integrität der Daten sichergestellt werden Die Daten müssen manipulationssicher sein

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

getJsonPayload-Methode

 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

Ich werde nicht über die validPayload-Methode sprechen, die relativ einfach und grundlegend ist. Der Schwerpunkt liegt auf der validMac-Überprüfung um sicherzustellen, dass die Daten nicht manipuliert werden.

 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

Die Methode „calcuteMac“ besteht darin, eine Signatur basierend auf den Originaldaten und Zufallswerten zu generieren und diese dann zum Generieren zu verwenden erneut eine Signatur

 protected function calculateMac($payload, $bytes)
 {
  return hash_hmac(
   'sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true
  );
 }
Nach dem Login kopieren

Die obige Entschlüsselung ist in drei Hauptschritte unterteilt

1. Bestimmen Sie die Integrität der Daten

2. Bestimmen Sie die Konsistenz von die Daten

3. Entschlüsseln Sie den Dateninhalt.

Diese Verifizierungssignatur hat etwas Seltsames. Sie ähnelt nicht unserer üblichen Verifizierung von Signaturen. Normalerweise überprüfen wir Signaturen, indem wir 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 Die Signatur erzeugt eine Signatur und vergleicht diese anschließend. 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 Binärwert der ursprünglich verwendeten Rohdaten, und der mit openssl_decrypt entschlüsselte Wert wird als Zufallszeichenfolge verwendet nach base64 Bits.

  • Beim Generieren einer Signatur zum Vergleich während der Entschlüsselung wird anstelle der Verwendung der Originalsignatur und der anschließenden Neugenerierung einer Signatur zum Vergleich basierend auf dem Inhalt der Originaldaten eine Signatur basierend auf der Originalsignatur generiert. und dann Nehmen Sie 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.

Verwandte Empfehlungen:

Wie man AES_ENCRYPT() und AES_DECRYPT() für die MySQL-Verschlüsselung und -Entschlüsselung richtig verwendet

Lösung für den Fehler „Kein unterstützter Verschlüsseler gefunden“ bei Verwendung von Laravel 5.1

Javascript – Entschlüsselung von encryptData im Applet wx.getUserInfo

Das obige ist der detaillierte Inhalt vonBeispiel für die gemeinsame Nutzung von Implementierungsmethoden zum Verschlüsseln und Entschlüsseln 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
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!