# LeetCode讀書會(7/29~8/04) 前後端加密的差別 / SQL Injection ## 前後端密碼加密(hash) ## -----瑋晨----- --- ![](https://i.imgur.com/Nq1DNQP.png) --- ## 加密方式 * Encode -- 只是換個方式來表達資料,例如Base64、encodeURL、decodeURL * Encrypt -- 必須要有金鑰(KEY),例如AES(對稱加密)、RSA(非對稱加密) * Hash -- Data -> Hash function(SHA-1、md5) -> Hash Value -- 無法反推回原字串 * [參考資料](https://medium.com/starbugs/what-are-encoding-encrypt-and-hashing-4b03d40e7b0c) --- ## 資料庫存放明文密碼 * 前後端分離架構,明文密碼的隱憂 * 資料庫洩漏 --- ## 如何加密? 1. Encrypt 加密 ![](https://i.imgur.com/QCegoq5.png) * 缺點: * KEY還是放在SERVER上,一旦洩漏密碼還是危險 * 員工若知道KEY,還是很防止資料洩漏 --- ## 如何加密? 2. HASH ![](https://i.imgur.com/ichbcCv.png) 登入時比對HASH值,若相同, __高機率__ 為本人,放行 * 缺點 ![](https://i.imgur.com/Q2jmyqU.png) * 因為大多數密碼格式其實相差不大,所以可以用暴力破解 ex. [彩虹表破解法](https://zh.wikipedia.org/wiki/%E5%BD%A9%E8%99%B9%E8%A1%A8) --- ## 如何加密? 3. HASH 加鹽 既然建表就可以從hash值反推回我的明文, __那就把明文弄得更亂__ 再HASH ![](https://i.imgur.com/KQcpY8Z.png) * 這樣的優點是反推會更複雜,遠超目前電腦的極限。 * 進階可以利用Bcrypt 再進行更複雜的加密 [參考資料](https://medium.com/starbugs/what-are-encoding-encrypt-and-hashing-4b03d40e7b0c) --- ## 前端有需要加密嗎? * 防人之心不可無 * 網站最好永遠,永遠不要有可能知道用戶的明文密碼。因為HTTPS只保證通信過程的安全,不保證服務器上數據的隱秘性 --- ## github登入 -- 前端沒加密 ![](https://i.imgur.com/wZbFtkU.png) * 明文傳送,但是確保安全,WHY? --> https * TLS 是可以保證我們和服務器端傳輸的安全性 * 這安全性主要包括三方面: 1. 機密性。(第三方截獲數據無法知道明文是什麼) 2. 數據完整性。(第三方篡改數據,會使得數據變得無效) 3. 認證。(交流雙方可以確認對方的身份,第三方無法偽裝成任何一方進行交流) * Public-Private-Key加密(保證第一個),對稱加密(保證第一個) * hash 散列函數(保證第二個), * CA機構(保證第三個)。 --- ## 為何前端需要加密? * 保護客戶的隱私 -> 在多個網站都使用同一個密碼是很普遍的現象 * https 有時不太可靠 -> [可參考](https://program-think.blogspot.com/2016/09/About-WoSign.html) * 隱憂,以HASH加密傳輸,若攻擊者拿到HASH還是可以進行登入 [前端要不要加密很有趣的討論](https://www.zhihu.com/question/25539382) ## -----瑋晨----- ### bcrypt(承翰) bcrypt 能夠將一個字串做雜湊加密,其中有個參數叫 saltRounds 是在密碼學中的加鹽(salt),加鹽的意思是在要加密的字串中加特定的字符,打亂原始的字符串,使其生成的散列結果產生變化,其參數越高加鹽次數多越安全相對的加密時間就越長。 #### 解析加密字串 加密後的 bcrypt 分為四個部分: ##### Bcrypt 該字串為 UTF-8 編碼,並且包含一個終止符 ##### Round (回合數)每增加一次就加倍雜湊次數,預設10次 ##### Salt (加鹽)128 bits 22個字元 ##### Hash (雜湊)138 bits 31個字元 ![img](https://ithelp.ithome.com.tw/upload/images/20180108/20107247r1tPcIUHFo.png) 參考資料:https://ithelp.ithome.com.tw/articles/10196477 -- Argon2資料-- https://medium.com/analytics-vidhya/password-hashing-pbkdf2-scrypt-bcrypt-and-argon2-e25aaf41598e ## SQL Injection --震瑋-- SQL injection中文譯作SQL注入、SQL隱碼。SQL Injection是一種常見的網路攻擊手法,藉由在輸入字串中夾帶惡意指令,試圖改變SQL語法上的邏輯,得以非法破壞、入侵資料庫伺服器,例如竊取使用者機密資料,帳戶資料,密碼等,甚至癱瘓整個系統。 #### SQL語法註解 ```sql /* -- # ``` #### SQL Injection範例 ```sql SELECT * FROM member WHERE account = 'ply' AND password = 'ply' ``` 如果只在帳號輸入欄位輸入「' or 1=1 /*」,SQL語法會變成: ```sql SELECT * FROM member WHERE account = '' or 1=1 /* AND password = "ply" ``` WHERE後面的條件判斷, account='' or 1=1 ,因為1=1數學式恆等,該判斷式永遠會成立,而/*是註解符號,因此該SQL語法實際效果如下: ```sql SELECT * FROM member WHERE account = '' or 1=1 ``` 藉由在字串中夾帶特殊字元,便可以改變SQL語法邏輯進而登入網站。 --宇軒-- **所以SQL該怎麼被防範** 為什麼我們不寫像這樣的語法 ```python= res = db.execute(f"SELECT * FROM member WHERE account = {account} AND password = {password}").fetchone() ``` 最常見的防禦方式為parameterized query(參數化查詢),該方法會先將SQL語法固定防止重構,以上方登入為例,SQL語法會固定為 ```sql= SET @account := XXX; SET @password := XXX; SELECT * FROM member WHERE account = @account AND password = @password ``` 此時就算在email或password中安插其他SQL語法,在參數化後都會只視為字串而非SQL語法,就算使用者輸入帳號/密碼為 a / b' OR '1'='1,依然只會查找帳號「a」,密碼是「b' OR '1'='1」的使用者,也無法執行其他SQL injection的操作了。 在python-mysql-connector的操作則會像是 ```python= res = db.execute("SELECT * FROM member WHERE account = %s AND password = %s", (account, password)).fetchone() print(res) ``` --宇軒-- ## Leetcode討論區