• python如何提取浏览器中保存的网站登录用户名密码


      python如何提取Chrome中的保存的网站登录用户名密码?

      很多浏览器都贴心地提供了保存用户密码功能,用户一旦开启,就不需要每次都输入用户名、密码,非常方便。作为python脚本,能否拿到用户提前保存在浏览器中的用户名密码,用以自动登录呢?必须有,小爬已经提前踩过很多坑,找到了可行的方案。

      以Chrome浏览器为例,浏览器中的用户数据(包含加密后的密码)都存在下图所示的位置中:

     

        文件的路径就像这样 C: => Users => => 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"
    复制代码
      核心搞定之后,还涉及到一个知识点,用于某个网站登录的用户名 以及加密后的密文存储在哪里?别急,还是之前提到的Local State文件,其实它是一个本地sqlite3数据库文件,我们可以借助sqlite3库以及sql语法轻松获取。当然需要先知道目标网站的域名,比如小爬就想取本地chrome浏览器中我自己保存用于登录博客园网站(base_url="cnblogs.com")的用户名密码。另外需要注意的是,同一个网站,浏览器是支持同时保存几组用户名密码的。代码示例如下:
    复制代码
     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
    复制代码

      还在围观吗?动手能力强的已经跃跃欲试,把它用到真正的办公自动化场景中了。希望这些对现实业务的思考和代码实现,能对您的工作有所启发。不管咋说,活到老,学到老。拒绝躺平,一起卷起来!

    快来关注本公众号 获取更多爬虫、数据分析的知识!

     

  • 相关阅读:
    Mac上解决dose not contain the JNI_CreateJavaVM symbol
    【Linux进阶】-- 1.python脚本实现守护进程daemon调度,启停等
    漏斗分析模型
    java毕业生设计校园绿化管理系统计算机源码+系统+mysql+调试部署+lw
    【Day_14 0510】▲幸运的袋子
    4T硬盘剩余很多提示“No space left on device“磁盘空间不足
    Linux常用命令— 目录和文件都能操作的命令
    java中集合遍历方法的选择
    进程和线程的区别
    【Python21天学习挑战赛】文件读写操作
  • 原文地址:https://www.cnblogs.com/new-june/p/17659190.html