写点什么

获取 chrome80 谷歌浏览器存储的指定网站 Cookie 数据方法详解

用户头像
老猿Python
关注
发布于: 2021 年 04 月 29 日
获取chrome80谷歌浏览器存储的指定网站Cookie数据方法详解

一、引言

说起来很惭愧,作为一个开了爬虫专栏的博主,对于需要登录再访问网站的爬虫应用,采用的是通过浏览器开发者模式获取 Cookie,再拷贝到网站访问的代码中构建 http 请求头的方式来实现的。


这两天仔细研究了一下谷歌浏览器 Cookie 的访问,发现是可以直接通过代码获取浏览器访问指定网站的 Cookie 的,但网站上相关方法都是基于 chrome 80 以前的版本,而此版本及以后的版本以前的方法都不行。最后找到了 CSDN 博友“whenyouarebigger”的《chrome 80+ sqlite3 cookie 解密》,找到了问题的原因。


根据 whenyouarebigger 博文的介绍做了些测试,发现该文介绍的内容还有些问题,不能直接运行,另外也没有构造成可以应用直接在请求头中使用的 Cookie。通过对比浏览器的 Cookie,最终找到了问题原因,终于彻底解决了该问题,今天总结出来供大家参考一下。

二、Chrome 浏览器加解密的机制介绍

2.1、chrome80 以前的版本的加解密机制

chrome80 以前的版本的加解密是直接通过 DPAPI 来进行加解密的:


  1. DPAPI 是 Windows 系统级对数据进行加解密的一种接口,用户无需自实现加解密代码,DPAPI 提供了经过验证的高质量加解密算法,提供了用户接口对密钥存储数据加解密,实现透明并提供较高的安全保证

  2. DPAPI 提供了两个用户态接口:CryptProtectData加密数据、CryptUnprotectData解密数据。因此 chrome80 以前的版本可以直接调用 CryptUnprotectData 对加密数据进行解密。

2.2、chrome80 以后版本的加解密机制

chrome80 以后版本的加解密机制与上面的大不同,其具体步骤为:


  1. 从环境变量 HOMEPATH 对应目录的\Google\Chrome\User Data\子目录下的 Local State 文件中读取读取一个值为 os_crypt 下的 encrypted_key;:Local State 文件为 chrome 用于存储本地状态(包括浏览器的不少状态信息,插件的详细信息等)的 json 文件。

  2. 将 encrypted_key 用 base64 进行解密,然后去除前 5 个字符,再通过 dpapi 解密剩余字符的值保存为 key;

  3. 将加密数据截取 3-14 位保存为 Nonce,15 位开始后的其他数据保存为 cipherbytes 加密数据,然后使用 key 作为密钥通过 asegcm 进行解密。

三、其他相关知识介绍

  1. chrome 的 Cookie 保存在本地环境变量 LOCALAPPDATA 对应目录的\Google\Chrome\User Data\Default子目录下的 Cookies 文件中,而 whenyouarebigger 博文中使用`=os.environ['HOMEPATH']+r'\AppData\Local\Google\Chrome\User Data\Default\Cookies'这种方式获取的路径缺少了驱动器路径;

  2. 谷歌 Cookies 是一个 sqlite3 的数据库,可以通过 Python 的 sqlite3 模块连接打开访问数据;

  3. 谷歌浏览器中的 Cookie 是一段小型文本数据,其数据由一个或多条记录组成,每条记录间用分号分隔,每条记录包括一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。Name/Value 设置 Cookie 的名称及相对应的值,对于认证 Cookie,Value 值包括 Web 服务器所提供的访问令牌;

  4. 谷歌浏览器中的 Cookie,可以通过 Sql 语句select name,encrypted_value from cookies where host_key ='hostname'获取,name 为 cookie 名字,encrypted_value 为加密的 cookie 值,hostname 为:'.'+网站域名,如‘.baidu.com

  5. 为了对 Cookie 数据进行解密,需要使用 json、base64、win32crypt 和 cryptography 库或模块,其中 json、base64 是 Python 内置的标准库,win32crypt 模块是 pywin32 库的模块,可以实现 DPAPI 方式的加解密,cryptography 是一个单独的标准 Python 加解密库,可以提供 asegcm 方式的加解密。pywin32 和 cryptography 库如果缺少则需要先安装,可以使用如下安装命令:


pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pywin32pip install -i https://pypi.tuna.tsinghua.edu.cn/simple cryptography
复制代码


  1. 通过 sqlite3 获取 Cookie 数据,必须设定数据库连接的 text_factory = bytes,因为加密数据为字节类型,不是字符串类型,否则就会在获取数据时报错“Could not decode to UTF-8 column 'encrypted_value' with text 'v10�M�gVI�}�.^�P=-���"���E4��'”类似的错误。这是《chrome 80+ sqlite3 cookie 解密》中没有介绍的;

  2. 由于指定通过 sqlite3 获得的 Cookie 数据都是 UTF-8 格式的 bytes 类型,而作为 Cookie 名的 Name 需要是 str 类型,必须要进行类型转换;

  3. 获取的 Cookies 是一条条记录,需要拼装成一个字符串,每条记录间用分号隔开。


`

四、案例实现代码

下面的代码根据上述介绍提供的完整获取 Chrome 浏览器存储的百度相关的 Cookies 的实现代码:


# -*- coding:'utf-8' -*-import time,traceback,sqlite3,os,json,base64
from win32crypt import CryptUnprotectDatafrom cryptography.hazmat.primitives.ciphers.aead import AESGCM
def decryptString(key,data): nonce,cipherbytes=data[3:15],data[15:] aesgcm=AESGCM(key) plainbytes=aesgcm.decrypt(nonce,cipherbytes,None) plaintext=plainbytes.decode('utf-8')
return plaintext
def getKey(): LocalState = os.environ['LOCALAPPDATA'] + r'\Google\Chrome\User Data\Local State' with open(LocalState, 'r', encoding='utf-8') as f: base64_encrypted_key = json.load(f)['os_crypt']['encrypted_key'] encrypted_key_with_header=base64.b64decode(base64_encrypted_key) encrypted_key=encrypted_key_with_header[5:] key = CryptUnprotectData(encrypted_key,None,None,None,0)[1] return key

def getChromeCookie(hostsUrl): cookiepath=os.environ['LOCALAPPDATA']+r"\Google\Chrome\User Data\Default\Cookies" if not os.path.exists(cookiepath): raise Exception('Cookies file not exist!')
sql = f"select name,encrypted_value from cookies where host_key = '.{hostsUrl}'" try: conn = sqlite3.connect(cookiepath) conn.text_factory = bytes res=conn.execute(sql).fetchall() conn.close() except Exception as e: print(e) key = getKey() cookieList=[] for row in res: cookieList.append( f'{str(row[0],encoding = "utf-8")}={decryptString(key, row[1])}') cookie = ';'.join(cookieList) return cookie

print(getChromeCookie('baidu.com'))
复制代码

五、小结

本文详细介绍了 chrome80 以上谷歌浏览器版本的加密数据解密方法、获取浏览器缓存本地文件中 Cookie 的方法及背景知识,并提供了获取浏览器中指定网站完整 Cookie 数据的实现代码,该代码获取的 Cookie 数据可以直接作为 http 请求头的 Cookie 值。


更多相关 moviepy 知识的介绍请参考 Python音视频剪辑库MoviePy1.0.3中文教程导览及可执行工具下载》的导览式介绍。


对于缺乏 Python 基础的同仁,可以通过老猿的免费专栏《 专栏:Python基础教程目录》从零开始学习 Python。


如对文章内容存在疑问,可在博客评论区留言,或关注:老猿 Python 微信公号发消息咨询。



发布于: 2021 年 04 月 29 日阅读数: 89
用户头像

老猿Python

关注

学问无遗力,功夫老始成。 2020.08.21 加入

CSDN 2020年博客之星季军、高级程序员、超50万行C语言项目开发经验 擅长领域:Python语言、PyQt界面程序开发、Moviepy音视频剪辑、OpenCV-Python图像处理、爬虫、5G、区块链、人工智能数学基础

评论

发布
暂无评论
获取chrome80谷歌浏览器存储的指定网站Cookie数据方法详解