python如何提取浏览器中保存的网站登录用户名密码
python如何提取Chrome中的保存的网站登录用户名密码?
很多浏览器都贴心地提供了保存用户密码功能,用户一旦开启,就不需要每次都输入用户名、密码,非常方便。作为python脚本,能否拿到用户提前保存在浏览器中的用户名密码,用以自动登录呢?必须有,小爬已经提前踩过很多坑,找到了可行的方案。
以Chrome浏览器为例,浏览器中的用户数据(包含加密后的密码)都存在下图所示的位置中:
文件的路径就像这样 C: => Users => <Your_Name> => AppData =>Local => Google => Chrome => User Data =>Local State
由于每台电脑的用户名是不确定的,因此小爬这里用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
还在围观吗?动手能力强的已经跃跃欲试,把它用到真正的办公自动化场景中了。希望这些对现实业务的思考和代码实现,能对您的工作有所启发。不管咋说,活到老,学到老。拒绝躺平,一起卷起来!
快来关注本公众号 获取更多爬虫、数据分析的知识!