python如何提取Chrome中的儲存的網站登入使用者名稱密碼?
很多瀏覽器都貼心地提供了儲存使用者密碼功能,使用者一旦開啟,就不需要每次都輸入使用者名稱、密碼,非常方便。作為python指令碼,能否拿到使用者提前儲存在瀏覽器中的使用者名稱密碼,用以自動登入呢?必須有,小爬已經提前踩過很多坑,找到了可行的方案。
以Chrome瀏覽器為例,瀏覽器中的使用者資料(包含加密後的密碼)都存在下圖所示的位置中:
由於每臺電腦的使用者名稱是不確定的,因此小爬這裡用python中的OS庫來動態得到:
local_computer_directory_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome","User Data", "Local State")
知道了具體位置後,我們需要先拿到加密後的密文,顯然該密碼肯定不是以明文的形式儲存在檔案中,否則安全無法保證。獲取密文之前,還得先知道用於加密的金鑰,這需要先安裝pycryptodomex庫,直接用pip來安裝即可。一切就緒,現在編寫一個獲取金鑰的python函數:
1 import os,json,base64,sqlite3,win32crypt,shutil 2 from Cryptodome.Cipher import AES 3 #需要安裝pip install pycryptodomex 庫 4 from datetime import datetime, timedelta 5 def fetching_encryption_key(): 6 '''動態獲取儲存使用者資料的檔案的路徑,然後讀出加密後的密文''' 7 local_computer_directory_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome","User Data", "Local State") 8 with open(local_computer_directory_path, "r", encoding="utf-8") as f: 9 local_state_data = f.read() 10 local_state_data = json.loads(local_state_data) 11 12 # decoding the encryption key using base64 13 encryption_key = base64.b64decode( 14 local_state_data["os_crypt"]["encrypted_key"]) 15 16 # remove Windows Data Protection API (DPAPI) str 17 encryption_key = encryption_key[5:] 18 # return decrypted key 19 return win32crypt.CryptUnprotectData(encryption_key, None, None, None, 0)[1]
有了這個金鑰,咱們還需要編寫一個解密的方法將密碼變成明文,考慮到Chrome瀏覽器的版本80之前和之後用了截然不同的加密手段,因此,對應的解密方法也不同,小爬將他們一併整合到解密的函數中:
def password_decryption(password, encryption_key): try: iv = password[3:15] password = password[15:] # generate cipher cipher = AES.new(encryption_key, AES.MODE_GCM, iv) # decrypt password return cipher.decrypt(password)[:-16].decode() except: try: return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1]) except: return "No Passwords"
1 def get_url_credential(base_url): 2 '''如果chrome瀏覽器本地儲存了OA密碼,則返回使用者和密碼列表,否則返回False''' 3 key = fetching_encryption_key() 4 db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local", 5 "Google", "Chrome", "User Data", "default", "Login Data") 6 filename = "ChromePasswords.db" 7 shutil.copyfile(db_path, filename) # 為了避免程式bug將原有的login Data 檔案損壞,複製一份出來供程式用 8 9 # connecting to the database 10 db = sqlite3.connect(filename) 11 cursor = db.cursor() 12 cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_last_used") 13 user_name,pass_word=None,None 14 userInfos=[] # 用於存放多組同一個網站的使用者名稱 密碼 15 for row in cursor.fetchall(): 16 main_url = row[0] 17 if base_url in main_url: 18 user_name = row[2] 19 pass_word = password_decryption(row[3], key) 20 userInfos.append([user_name,pass_word]) 21 cursor.close() 22 db.close() 23 try: 24 os.remove(filename) 25 except: 26 pass 27 return userInfos
還在圍觀嗎?動手能力強的已經躍躍欲試,把它用到真正的辦公自動化場景中了。希望這些對現實業務的思考和程式碼實現,能對您的工作有所啟發。不管咋說,活到老,學到老。拒絕躺平,一起捲起來!
快來關注本公眾號 獲取更多爬蟲、資料分析的知識!