# 使用PostgreSQL Array 與函數產生密碼 ## 關於密碼的一些事情 最近在BackendTW 有一篇關於密碼的 [傳送門](https://www.facebook.com/groups/backendtw/posts/3127969964003525/) 在此先不去討論網站密碼該怎樣存,相信這些對本文的讀者來說,不需要再重複多說了. 個人密碼的管理,有的人會使用密碼管理工具.有的人是可能有幾組常用密碼,這篇的使用者,可能就是這樣情況,這樣當網站的密碼不安全時,就連帶影響了. 現在大家都已經有共識,就是密碼長度要夠長,以提高安全性,但是夠長的卻又不好記,就容易只使用幾組. 所以若我們有比較容易記得的文句當基礎,來產生一串長長的密碼,這樣就很方便了. ## PostgreSQL 的 Array 又出現了 最近介紹了不少Array的應用,這次還是要使用它. 來看一下例子 ```sql= select string_to_array('佐山愛',null); string_to_array ----------------- {佐,山,愛} (1 row) select unnest(string_to_array('佐山愛',null)); unnest -------- 佐 山 愛 (3 rows) select sn, elem from unnest(string_to_array('佐山愛',null)) with ordinality as s(elem, sn); sn | elem ----+------ 1 | 佐 2 | 山 3 | 愛 (3 rows) -- PG14版以後有 string_to_table() select string_to_table('佐山愛', null) as word; word ------ 佐 山 愛 (3 rows) ``` ## 來產生一些密碼吧 ```sql= -- 使用了digest(), 所以需要先安裝 pgcrypto create extension pgcrypto; with t1(poem) as ( values ('春風十里揚州路,秋野千尋長谷川。') , ('勁草疾風脱韁馬,橫山美雪加藤鷹。') ), t2 as ( select unnest(string_to_array(poem,null)) as word from t1 ) select word , encode(digest(word, 'sha256'), 'base64') , encode(digest(word, 'md5'), 'base64') from t2; word | encode | encode ------+----------------------------------------------+-------------------------- 春 | s8M7errwE2CnGg7rGR2El0AYzfJHpfcqhFstP8uUx8c= | 3SAZKPd9AhHIJCP6SpPPeA== 風 | tEeOMwjgNnJwmn1HIRfZVFgk/lVOBL+2xsKtBknvCGA= | u0Jb317RoCrvTUTwjBQQ6w== 十 | /H7dOZpcS5NyPrDAkb9k5W4kwwGVwVGQZ8aFE6TSyPs= | GBJFcgt3dOdkzxAA5WnV0g== 里 | efQ95uO8n9XrgXtACeCpzNlDASlj9jrXvwgEuj/WeEg= | /4dekHQU8xUXVSlBj9zpug== 揚 | QznOCFHj60w9dzZ6gesFk/Zoc3gQIng+IIFvCry6S5Q= | MVsksgWNLlWQiHRLT0xZig== 州 | cwB94qQxObdVXGgiFi8+eIaaPWri5PwbFpPXL2mKBL4= | sfSPlHyreXFiNuuw5L0qZg== 路 | CceATk/4DU9+a9GjTDlQd2ZAgoikiA1WcIQnjxyFv1c= | 0Eeif0Lth7yzdqq4xgrXwg== , | rZRk2hYajVrjcJ7JS6rZneEWZL+ttdAtlMr3L6O+ogM= | 07mPDDiizvk/5zzDMYjq0g== 秋 | Wi5eSxKkLrAVAHAdupzuyAFW5qdRai5qOfr3TTDqtPw= | /fMf86iA/3x0NrY4hGPrVw== 野 | WADLBxBQuIXpIG/DMgGyYDwsWsKfUB1gKHso3r+TA8M= | gGuA8ti/BLZfUQm60FvFyg== 千 | I9hi3s9PFKsLRG4gHIhgcWrR4qcid1RzpzWg+z5DtbU= | yCHlIjE14qbQHDbzBk0w9g== 尋 | FDH9OwrgzR2+wvPt7jTg8Yr5Kwrr0Pz2M/vXxB0p7IM= | v7iP+fIOdA6vJf9jO7bTsg== 長 | Y7olb9tKkGSUjnR6MGWzN/pXmUcoaNm/1C3ySyWjq8Q= | jSJtsDUOQj7uDKNy4A10kw== 谷 | u17f197qVyma+xvL+74+sIe28a7+2AfMwMXMovsXL6w= | 7hdu/tZEFQ6iGrlObeYzYQ== 川 | tarmk1gdEsgKKhkFg4BNCXpNyesJK3+PoGJiU4KF9Us= | 4TDb4KXCXAI2y2CDPRUPRw== 。 | 6w1YhFabOY5HW4nnegaMbFdaAGT/anL6/BcxAsTPzVc= | gRl8LQKzp8VMvUmM5VpzyA== 勁 | QGaYUbLRwRqYK2XnLoAMKdHlvN4ieYa/tBahpnX4OOE= | s7G2+WY8F82TLHrIdpZc0g== 草 | kbJGtdvAVIDeR83c6wJ+eqRO0/0L/bdF1eC99ue08ec= | fTz+jE7L2tZTnguNUNkSFQ== 疾 | HLoAaO0pifJwKnMxnLcKaBgM0ob8cem7wW8A/tkYkLQ= | 1PyKwBakMsSJZafqomgkPA== 風 | tEeOMwjgNnJwmn1HIRfZVFgk/lVOBL+2xsKtBknvCGA= | u0Jb317RoCrvTUTwjBQQ6w== 脱 | 9opnNMKU6CBVan2Axkq+XGeAZNAhOhO5T+f8IYRfSlg= | 7VfuToziCEIsHR13gQ9FtQ== 韁 | ttMMCswNG9r2J3IdvDapwfmFAQbbC10eaewKZsBlH0I= | mBae6z/xOCIcBk1hoFdhsQ== 馬 | kRPk83zkTvasC0ZjCcjkWmAU1N47nFTE5/jBLsUeFzI= | aoU8qZlvNkoukuKkdfr4rw== , | rZRk2hYajVrjcJ7JS6rZneEWZL+ttdAtlMr3L6O+ogM= | 07mPDDiizvk/5zzDMYjq0g== 橫 | X4TAfJ2cHIL9iF8rf9NRFwqQ9LawS86M/F74cadjJ3E= | 4WK4FcNA0cz0aJNOHAgmUg== 山 | SGJUCimXYrPwkCV+u2l27B0FykYN4KGhle6FaQYa1sA= | hvqcgtgSkE5BiXtNSyocjw== 美 | Thh+23MAZs1A5CIzuH9M+/zzuzoOiH66n6cEO+DLQBE= | WpOicFIRTq54mj3UKWtl8g== 雪 | UwWP4uA8ANk8S6k2GInddWnX17lnTtFyJm7mYmUgjMY= | xPzNjdEfl27MbB5XRWl5Sg== 加 | 8PAye8VXUNbENzl3ci3D/tuWeMZnsQ3vV8/GmXscDAs= | hb4I+SYKjJMPMzIBr+bFTQ== 藤 | /83B+1OoW30X1mautEXi9qPLmFj1mW9IGNSkwz+3ng4= | e4ea3ikQSl+6HWp7ajISDQ== 鷹 | PJKc+RpoHOrSRnjUT853PFil+1S423CndV77WMqgQX0= | Af0i/srKJBMAHIS0niLVMg== 。 | 6w1YhFabOY5HW4nnegaMbFdaAGT/anL6/BcxAsTPzVc= | gRl8LQKzp8VMvUmM5VpzyA== (32 rows) ``` 可以觀察到,。 產生的都一樣,這樣不至於會不一致. 我們就可以善用許多的詩詞,或是名言佳句,來產生密碼. 因為我是使用了base64, 所以特殊符號就不多,有需要的話,可以自行再加工. ## 但是,這樣手機不方便啊.... 我們不一定要在手機上執行PostgreSQL,我們可以利用db<>fiddle [傳送門](https://dbfiddle.uk/bFaLPiAi) 手機上只要存連結,很方便就可以使用了. ## 一些提醒 密碼的使用,最好做一些分級,重要的帳號密碼與一些趣味性或是臨時性的最好使用不同的.不要把安全依賴別人的正常發揮. ## 有人嫌棄說 entropy 完全不夠 我這篇主要的目的是要做到方便產生,要增加的話,也可以改一下囉. ### 變化一下 ```sql= with t1(gal) as ( values ('佐山愛'),('小島南') ,('初川南'),('相澤南') ,('小宵虎南') ) select gal , encode(digest(gal, 'sha512'), 'base64') from t1; gal | encode ----------+------------------------------------------------------------------------------ 佐山愛 | EY28kSyUauIYQ/Hx4dLGrdYz37XDH7t8OJL+E6pSx0DLrRNTdK9+g+nLzgkVyPGxOPwUr5W1dT9++ | RW33yMFaEA== 小島南 | MaCyIhKkH9qjD6NCm7XE6+zuqBlBf4O5b8PS3piX+K/0oANxhYTtBJQJoBW69fc+yfSSNyItLOjN+ | 5C0YCzIliw== 初川南 | BZoLbEmo6ovql6KrFt59GQ4xPJ8FM3BloEs5BHnVX9tnc4oiO6qARHvQ7X5sZFP9iQPWkvqArCgG+ | NPA1le7nyw== 相澤南 | vC9OXkAqvD9uuEbrBdbcrJYtnw/mJxB6Ewv8A8ZtckXqpQx7/Q+Gmfxx4+TpPH3ATf/9nrpqXxdg+ | rb05Wwc8hw== 小宵虎南 | JOoK3CC8NWFdphqaqSJsmp+nQZZU5yEaz7X3/9wGAKEUkpwylsL/SA2M/e0WGnuIaFf8jfa9G7IV+ | CCLdZh/geg== (5 rows) ``` 這樣不展開內容,其實很好寫,但不是我的目的啊. 就不想記那樣多,只是要用個好記的句子,然後產生多一些的密碼,拿來使用. 若需要更高強度的,那是另外的議題了. ## 感謝 感謝佐山愛,秋野千尋,橫山美雪,小島南,初川南,相澤南,小宵虎南還有加藤鷹.