聊聊 Laravel 中 App_KEY 的作用

2022-10-28 22:00:24
Laravel 中的 App_KEY 到底有什麼用?下面本篇文章給大家介紹一下App_KEY 的作用,希望對大家有所幫助!

Laravel 9 保姆級視訊教學,想學不會都難!進入學習

每次 Laravel 開發人員新建或克隆 Laravel 應用時,生成 application keyAPP_KEY 是最重要的初始步驟之一。

最近的 Laravel 安全更新修復了一個 APP_KEY 用途相關的漏洞。為了利用此漏洞,首先需要有權存取生產版 APP_KEY。解決此漏洞最簡單的方法是轉換(更改)您的 APP_KEY。這導致我們中的一些人提出了一個問題:應用程式金鑰有什麼作用?更改涉及什麼?管理 Laravel 應用程式中的這些金鑰的最佳實踐是什麼?

在這篇文章中,我們將討論 APP_KEY 做和不做的事情,關於它與使用者密碼雜湊的關係的一些常見誤解,以及安全地更改 APP_KEY 的簡單步驟而不會丟失對您資料的存取許可權。

Laravel 安全修復

8月初,Laravel 5.5 和 5.6 收到了與 Cookie 序列化和加密有關的安全修復程式。一方面,修復很簡單,大多數應用程式可能沒有受到影響。另一方面,這是一個嚴重的安全風險,表明我們的社群需要更好地瞭解 APP_KEY 的工作方式。

要利用此安全漏洞,需要有人知道您的 APP_KEY,這就是為什麼我要帶您詳細瞭解您的金鑰,為什麼重要以及如何更改它的原因。

有關安全修補程式的資訊,請參閱以下資源:

什麼是 APP_KEY

應用程式金鑰是一個32位元字元的隨機字串,儲存在 .env 檔案中的 APP_KEY 金鑰中。 Laravel 安裝程式會自動為您生成一個,因此您只會在克隆現成應用程式時注意到它的缺失。

您之前可能看到過此錯誤:

RuntimeException

要建立新金鑰,您可以自己生成一個金鑰並將其貼上到您的 .env 中,或者可以執行 php artisan key:generate 讓 Laravel 為您建立並自動插入一個金鑰。

應用程式執行後,便會在一個地方使用 APP_KEY:cookie。Laravel 將金鑰用於所有加密的 cookie (包括對談 cookie),然後再將其交給使用者瀏覽器,並使用它解密從瀏覽器讀取的 cookie。這樣可以防止使用者端更改其 cookie 併為其授予管理員特權或模擬應用程式中的其他使用者。加密的 cookie 是 Laravel 中的重要安全特性。

所有這些加密和解密操作均由Laravel通過 Encrypter 使用 PHP 內建的安全工具處理,包括 OpenSSL。我們不會在這裡仔細研究加密的工作原理,但是如果您想了解更多資訊,我鼓勵您閱讀更多關於 PHP implementation of OpenSSLopenssl_encrypt function.

關於密碼雜湊的常見誤解

在 Laravel 社群中,包括我自己直到最近,一個非常普遍的誤解是任務 APP_KEY 用於登入密碼的加密。幸運的是,事實並非如此!我覺得這導致許多人認為 APP_KEY 是不可更改,除非重置所有使用者的登入。

密碼並非被加密,而是被 雜湊雜湊.

Laravel 的密碼使用 Hash::make()bcrypt() 進行雜湊處理,但都不使用 APP_KEY。讓我們看一下 Laravel 中的加密和雜湊。

加密與雜湊

Laravel 中有兩個主要的 facades:Crypt (對稱加密) 和 Hash (單向雜湊加密)。密碼被 雜湊雜湊,而 cookies 被(可選) 加密。讓我們看一下差異。

對稱加密

假設我想向我的朋友亞瑟 (Arthur) 傳送一個祕密訊息。上一次我們在一起時,我們倆一致確定了一個祕鑰:

$key = "dont-panic";
登入後複製

我想給他發一條短訊息,只有該金鑰才能解密。我將使用我最喜歡的行業標準的開源加密函數 openssl_encrypt() (Laravel的 Crypt 使用的就是這個)再加上我倆共同的 $key 進行文字加密的字串傳送給他:

$message = "So long and thanks for all the fish";
$key = "dont-panic";
$cipher = "AES-256-CBC";
echo openssl_encrypt($message, $cipher, $key);

// JJEK8L4G3BCfY0evXDRxUke2zqAzq6i7wL/Px4SjaEHXqt3x7hsj4+PhVQaH4ujX
登入後複製

我可以用任何方式將這個字串傳送給亞瑟;由於我們是僅有的兩個擁有私鑰的人,因此我不擔心其他人會閱讀該訊息。

fake tweet with encrypted string

當 Arthur 收到時,他將使用我們的私鑰解密此過程。這是其中的 對稱 部分:我們能夠加密和解密而不會丟失資訊。

$secret = "JJEK8L4G3BCfY0evXDRxUke2zqAzq6i7wL/Px4SjaEHXqt3x7hsj4+PhVQaH4ujX";
$key = "dont-panic";
$cipher = "AES-256-CBC";
echo openssl_decrypt($secret, $cipher, $key);

// So long and thanks for all the fish
登入後複製

Laravel 使用 APP_KEY 作為加密金鑰,對傳送者和接收者的 cookie 使用相同的方法。使用相同的應用程式金鑰對響應 cookie 進行加密,傳送給使用者,在接下來的請求中進行讀取和解密。

單向雜湊

我們的對稱加密範例具有很多潛在的用途,但是所有這些都涉及最終需要解密被加密的訊息。

但是,當涉及到諸如使用者密碼之類的東西時,您永遠都不應有解密它們的方法。

這意味著我們的 Crypt 方法將無法使用,因此無法基於我們擁有的金鑰。相反,我們需要一個 hashing 函數,它應該是:

  • 快速: 計算機應該能夠快速生成雜湊

  • 確定性: 雜湊相同的輸入總是給出相同的輸出

  • 隨機性: 更改輸入的單個字母應會徹底更改輸出

  • 唯一: 衝突率(將不同的輸入雜湊到相同的輸出)應該很小

  • 難以暴力破解: 應該很難對所有可能的輸入進行雜湊以猜測我們的原始輸入

您可能已經熟悉許多單向雜湊演演算法:MD5 和 SHA-1 可以快速計算,但不是最安全的(它們在上述第 4 和第 5 項上較弱)。

Laravel 雜湊實現了原生 PHP 的 password_hash() 函數,預設為一種稱為 bcrypt 的雜湊演演算法。對於單向雜湊來說,這是一個很好的預設值,您不需要更改它(儘管 Laravel 現在也提供了 一些其他 雜湊方法。)

use Illuminate\Support\Facades\Hash;

$password = "dont-panic";
echo Hash::make($password);

// $2y$10$hEEF0lv4spxnvw5O4XyLZ.QjCE1tCu8HjMpWhmCS89J0EcSW0XELu
登入後複製

如果您曾經檢視過 users 表,則可能看起來很熟悉。這是什麼意思:

  • $2y$ 使用 blowfish 演演算法進行雜湊雜湊 (bcrypt)
  • 10$ 「成本」因素(越高意味著要花更長的時間進行雜湊)
  • hEEF0lv4spxnvw5O4XyLZ. 22位字元的 「salt」
  • QjCE1tCu8HjMpWhmCS89J0EcSW0XELu 雜湊輸出

由於這是單向雜湊,因此我們 無法 對其進行解密。我們所能做的就是對它進行測試。

當使用此密碼的使用者嘗試登入時,Laravel 會對其密碼輸入進行雜湊處理,並使用 PHP 的 password_verify() 函數將新雜湊與資料庫雜湊進行比較:

use Illuminate\Support\Facades\Hash;

$input = request()->get('password'); // "dont-panic"
$hash = '$2y$10$hEEF0lv4spxnvw5O4XyLZ.QjCE1tCu8HjMpWhmCS89J0EcSW0XELu';
return Hash::check($input, $hash);

// 正確
登入後複製

您會注意到,只有在需要對稱(可逆)加密時,Laravel 才需要一個金鑰 (APP_KEY)。使用者密碼的儲存永遠不可逆,因此完全不需要 APP_KEY

但這並不意味著您的金鑰應該被粗心對待。相反,請像對待其他任何生產憑證一樣對待它:使用與 MySQL 密碼或 MailChimp API 金鑰相同的注意和安全性。

更改金鑰

任何良好的憑證管理策略都應包括 輪換: 定期(例如每6個月)或在特定情況下(例如員工離職)更改金鑰和密碼。

幸運的是,您只需要記住一些事情,就可以輪換你的 APP_KEY

多臺伺服器

如果您從多臺伺服器提供相同的應用程式,則需要更新每臺伺服器上的金鑰。

現有使用者的 sessions (cookies)

更改 APP_KEY 後,當前登入到您的應用程式的所有使用者的對談均將失效。在最佳時間安排您的金鑰輪換,以最大程度地減少給使用者帶來的不便。

您已加密的其他資料

儘管 cookie 的安全性是 Laravel 唯一使用 APP_KEY 作為框架的地方,但是您的應用程式中可能會包含用於加密資料的自定義程式碼。如果您使用 Laravel 的加密功能,請制定並測試一個計劃,以使用舊金鑰解密該資料,然後使用新金鑰重新加密。

設定新的APP_KEY

首先,將現有的 APP_KEY 複製到其他地方,以防萬一更改金鑰會產生意外的副作用。

在嘗試在生產伺服器上輪換 APP_KEY 之前,請嘗試在本地計算機上輪換 APP_KEY,以確保一切順利。準備好後,執行 php artisan key:generate

[jbathman my_app]# php artisan key:generate
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? (yes/no) [no]:
> yes

Application key [base64:x2SHH01+2R+vwv09YcrvXqdFJ+bbqgT9gW4njcYLjDE=] set successfully.
登入後複製

就是這樣!如果要生成金鑰而不修改您的 .env 檔案,請包含 --show 標誌:

[jbathman ~/my_app]# php artisan key:generate --show
base64:c3SzeMQZZHPT+eLQH6BnpDhw/uKH2N5zgM2x2a8qpcA=
登入後複製

要點

  • 更改APP_KEY不會影響使用者密碼
  • 如果您更改APP_KEY,會導致 session (通過 cookie 實現)無效,所有當前使用者被登出
  • 不要害怕您的 APP_KEY
  • 您應該有一個策略來定期輪換 APP_KEY 以及其他憑據和金鑰
  • 如果您的程式碼已手動使用 Laravel 的加密器,則需要制定計劃以使用舊金鑰解密其加密資料,然後使用新金鑰重新加密。

原文地址:https://tighten.co/blog/app-key-and-you

譯文地址:https://learnku.com/laravel/t/41250

【相關推薦:】

以上就是聊聊 Laravel 中 App_KEY 的作用的詳細內容,更多請關注TW511.COM其它相關文章!