周末將兩年半前買的 "Python 金融市場大賺錢投資聖經" 這本書帶回鄉下看, 我記得裡面有寫一些網路爬蟲的密技, 在其中第三章看到作者描述如何用 AES 為帳號密碼等機敏資料加密, 覺得還蠻有用的, 今天就來測試看看唄.
1. 下載 AES-Encryption :
到下面這個 GitHub 下載 AES-Encryption 的模組 :
按右上角的 Code 鈕選擇 Download ZIP 下載壓縮檔 :
將此壓縮檔 AES-Encryption-main.zip 解開, 如果產生兩層 AES-Encryption 資料夾, 就複製最下層的 AES-Encryption 資料夾到工作目錄下, 例如我的工作目錄是 D:\python\test\ 則子目錄 AES_Encryption 底下就是解開的兩個 .py 檔 :
第一個模組 en_decrype.py 利用一個第三方模組 Crypto 來做 AES 加密解密作; 第二個模組 encrype_process.py 則是利用 en_decrype.py 編寫了加密函式 input_new_encrype() 與解密函式 check_encrype(), 不過實際上使用時只需要呼叫 check_encrype() 即可, 若未找到密鑰名稱, 它會自動呼叫 input_new_encrype() 讓你輸入帳號密碼與名稱來建立密鑰. 這三個模組關係如下 :
Crypto
|__ encrype_process
|__ encrype_process
所以要讓 check_encrype() 能用必須先有 Crypto 模組才行. Crypto 模組在 Python 中正式名稱是 pycrypto, 不過此套件已經停止更新很久了, 必須改安裝它的延伸套件 pycryptodome, 它裡面就有 Crypto 模組, 參考 :
2. 安裝 pycryptodome 套件 :
可以使用 pip install 指令直接安裝 :
pip install pycryptodome
D:\python\test>pip install pycryptodome
Collecting pycryptodome
Using cached pycryptodome-3.20.0-cp35-abi3-win_amd64.whl.metadata (3.4 kB)
Using cached pycryptodome-3.20.0-cp35-abi3-win_amd64.whl (1.8 MB)
Installing collected packages: pycryptodome
Successfully installed pycryptodome-3.20.0
我在 Thonny 套件管理安裝了最新版的 v3.20.0 :
安裝完就可匯入 Crypto 模組了 :
>>> import Crypto
>>> dir(Crypto)
['Cipher', 'Hash', 'Protocol', 'Random', 'Util', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'version_info']
上面 en_decrypt.py 裡面第一行就是從 Crypto.Cipher 匯入 AES 類別來進行加密與解密 :
from Crypto.Cipher import AES
但我們只要直接使用上面 AES-Encryption 套件中第二個模 encrype_process.py 的 check_encrype() 函式就可以進行加密解密了.
3. 使用 AES_encryption 套件 :
使用 AES_Encryption 套件進行加密解密只要從它的 encrype_process 模組中匯入全部函式即可 :
from AES_Encryption.encrype_process import *
>>> from AES_Encryption.encrype_process import * # 注意是 encrype 不是 encrypt
不過 encrype_process 模組中的 input_new_encrype() 函式是作者為了 Gmail 登入帳密而特製, 我將其改為較一般化的設定指引, 將其中 print() 與 input() 中的英文提示修改如下 :
def input_new_encrype(fuc_name,key_path,result_path):
print(f'名稱:{fuc_name}')
user_id = input('帳號:')
password = input('密碼:')
print(result_path)
result_file_path = (result_path+'encrype.config').replace('\n','')
key = get_key(key_path,result_path)
user_encrype = aes_encrypt(user_id, key)
password_encrype = aes_encrypt(password, key)
store_encrype = dict()
store_encrype['name'] = fuc_name
store_encrype['user_id'] = user_encrype
store_encrype['password'] = password_encrype
with open(result_file_path, 'a') as outfile:
json.dump(store_encrype, outfile)
outfile.write('\n')
outfile.close()
print('加密完成!')
return user_id,password
參考 :
然後設定儲存金鑰檔與設定檔的資料夾路徑變數, 注意, 最好不要放在工作目錄下, 否則打包時很容易把金鑰都打包進去分享給他人, 其次是路徑結尾必須有斜線 "/", 例如 :
>>> key_path="D:/key/" # 金鑰路徑
>>> config_path="D:/config/" # config 檔路徑
然後呼叫 check_encrype() 函式並傳入金鑰名稱, 金鑰路徑, 與設定檔路徑, 如果金鑰名稱存在會傳回解碼後的帳號與密碼組成之 tuple, 否則會出現輸入框要求設定金鑰名稱與鑰加密之帳密 :
user_id, password=check_encrype(name, key_path, config_path)
例如要加密我的網站 tony1966.cc 的登入帳密 :
>>> user, pwd=check_encrype('tony1966.cc', key_path, config_path)
名稱:tony1966.cc
帳號:admin
密碼:123456
D:/config/
加密完成!
這時檢視 D 碟會發現已建立 key 與 config 這兩個資料夾, 裡面分別有 key.key 與 encrype.config 這兩個檔案 :
用 utf-8 編碼格式開啟 key.key 會發現是不可讀之亂碼 :
�����\=�NA��6w�|���Y���7�
開啟 encrype.config 則是加密過的明碼 :
{"name": "tony1966.cc", "user_id": "SgALjY8Tq7EnCo2uM45Z/MyIXtUU65qJDgDEDQv5jKE=\n", "password": "RlqD34SyRjK/Q3tGB9jx3dycB0PB9HiW1wrCtYfdYsU=\n"}
再次執行 check_encrype() 時因為有找到金鑰名稱 tony1966.cc 所以就傳回解碼後的帳密 :
>>> user, pwd=check_encrype('tony1966.cc', key_path, config_path)
>>> user
'admin'
>>> pwd
'123456'
這樣就能增強帳號密碼的安全性了. 如果要重設帳密, 只要將 key 與 config 這兩個資料夾刪除, 重新呼叫 check_encrype() 就可以再次設定了. 當然也可以用來儲存 OpenAI API 的 key, 例如 name 名稱可以取名為 tony1966_openai_key, 前面是註冊的 email 帳號 (我有多個帳號), 帳號就用 email, 而密碼就輸入 API Key, 解密回來時就用 password 當 API Key 用.
2024-04-15 補充 :
我把修改後的 AES_Encryption 資料夾壓縮後放在 GitHub :
# https://github.com/tony1966/tony1966.github.io/blob/master/test/python/security/AES_Encryption.zip
沒有留言:
張貼留言