laravel 中的 app_key 到底有什么用?下面本篇文章給大家介紹一下app_key 的作用,希望對大家有所幫助!
每次 laravel 開發人員新建或克隆 Laravel 應用時,生成 application key 或 APP_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,這就是為什么我要帶您詳細了解您的密鑰,為什么重要以及如何更改它的原因。
有關安全修補程序的信息,請參閱以下資源:
- 安全更新(5.6.30)發行說明:https://learnku.com/docs/laravel/5.6/upgrade#upgra…
- 安全更新(5.5.42)發行說明:https://learnku.com/docs/laravel/5.6/upgrade#upgra…
什么是 APP_KEY?
應用程序密鑰是一個32位字符的隨機字符串,存儲在 .env 文件中的 APP_KEY 密鑰中。 Laravel 安裝程序會自動為您生成一個,因此您只會在克隆現成應用程序時注意到它的缺失。
您之前可能看到過此錯誤:
要創建新密鑰,您可以自己生成一個密鑰并將其粘貼到您的 .env 中,或者可以運行 php artisan key:generate 讓 Laravel 為您創建并自動插入一個密鑰。
應用程序運行后,便會在一個地方使用 APP_KEY:cookie。Laravel 將密鑰用于所有加密的 cookie (包括會話 cookie),然后再將其交給用戶瀏覽器,并使用它解密從瀏覽器讀取的 cookie。這樣可以防止客戶端更改其 cookie 并為其授予管理員特權或模擬應用程序中的其他用戶。加密的 cookie 是 Laravel 中的重要安全特性。
所有這些加密和解密操作均由Laravel通過 Encrypter 使用 PHP 內置的安全工具處理,包括 OpenSSL。我們不會在這里仔細研究加密的工作原理,但是如果您想了解更多信息,我鼓勵您閱讀更多關于 https://learnku.com/docs/laravel/5.6/upgrade#upgra… 和 openssl_encrypt https://learnku.com/docs/laravel/5.6/upgrade#upgra….
關于密碼哈希的常見誤解
在 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
我可以用任何方式將這個字符串發送給亞瑟;由于我們是僅有的兩個擁有私鑰的人,因此我不擔心其他人會閱讀該消息。
當 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?IlluminateSupportFacadesHash; $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?IlluminateSupportFacadesHash; $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