Facebook登入协议逆向解析:从加密参数到实战应用

张开发
2026/4/14 15:25:26 15 分钟阅读

分享文章

Facebook登入协议逆向解析:从加密参数到实战应用
1. Facebook登入协议逆向分析入门最近在研究各大社交平台的登入协议发现Facebook的加密机制确实有点意思。作为一个日活用户超过20亿的超级平台它的安全防护措施自然不容小觑。今天我就带大家一步步拆解Facebook登入过程中的关键加密参数手把手教你如何逆向分析并应用到实际项目中。先说说为什么我们要研究这个。现在很多自动化工具都需要模拟用户登录但直接使用账号密码明文传输风险太大。Facebook采用了一套成熟的加密方案特别是对密码的处理非常严谨。我们逆向分析的目的不是破解而是理解这套机制的工作原理这对开发安全的登录系统很有参考价值。打开Facebook登录页面按F12调出开发者工具在Network面板观察登录请求。你会发现提交的表单中有两个关键参数特别引人注目lgndim和encpass。这两个就是我们要重点研究的加密参数。前者看起来像是Base64编码的数据后者则是经过复杂加密处理的密码。2. 解密lgndim参数2.1 初步分析lgndim参数乍一看像是Base64编码的字符串。我在控制台直接用JavaScript的atob函数尝试解码果然得到了可读的明文数据。这个参数实际上包含了三个数值屏幕宽度、屏幕高度和色彩深度。举个例子假设你的屏幕分辨率是1920x1080色彩深度是24位那么编码后的lgndim参数解码后大致是这样的格式1920:1080:24。Facebook用这个参数来收集客户端的基本设备信息可能是用于风控或用户体验优化。2.2 实际应用在实际模拟登录时这个参数其实可以固定。我测试发现即使用不同的分辨率值登录也能成功。这说明Facebook目前对这个参数的校验并不严格。不过为了模拟得更真实建议还是按照实际设备的分辨率来生成这个值。生成lgndim的JavaScript代码很简单function generateLgndim(width, height, colorDepth) { const str ${width}:${height}:${colorDepth}; return btoa(str); }3. 破解encpass密码加密3.1 定位加密位置encpass参数才是真正的重头戏。这个参数是对用户密码的加密结果保护机制要严密得多。通过全局搜索encryptPassword我们很快就能定位到加密函数的位置。在Facebook的登录流程中密码加密发生在点击登录按钮之后。通过断点调试可以看到加密函数调用栈大致是这样的f.encryptPassword(d.keyId, d.publicKey, e.value, g)其中d.keyId和d.publicKey是加密所需的密钥对e.value是用户输入的明文密码g是当前时间戳3.2 获取加密密钥关键在于d这个对象从哪来。通过进一步分析发现它来自i.loginFormParams。有意思的是这个值在单次会话中是固定的也就是说我们只需要在登录前获取一次就行。更妙的是这些密钥其实就藏在首页HTML源码里。用正则表达式匹配keyId和publicKey就能提取出来。比如publicKey通常以AAAA开头长度约400多字符。获取密钥的伪代码如下async function getEncryptionKeys() { const homepage await fetch(https://www.facebook.com); const html await homepage.text(); const keyId html.match(/keyId:([^])/)[1]; const publicKey html.match(/publicKey:([^])/)[1]; return {keyId, publicKey}; }4. 逆向加密算法4.1 分析加密流程进入encryptPassword函数内部会发现Facebook主要使用了Web Crypto API进行加密。具体来说它采用了RSA-OAEP算法这是一种非对称加密方式安全性很高。加密过程大致分为三步导入公钥使用OAEP填充方案加密数据将加密结果转换为Base64格式值得注意的是整个过程都是异步的。这在浏览器环境中没问题但如果要在Node.js中实现就需要特殊处理。4.2 Node.js实现方案在Node.js环境下我们可以使用crypto模块来实现相同的加密逻辑。但由于Node的crypto是同步的而Web Crypto API是异步的直接移植会有问题。解决方案有两种使用deasync库将异步转为同步不推荐可能造成性能问题保持异步流程用Promise/async-await处理推荐这里给出第二种方案的实现代码const crypto require(crypto); async function encryptPassword(keyId, publicKey, password, timestamp) { const buffer Buffer.from(publicKey, base64); const encrypted crypto.publicEncrypt({ key: buffer, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: sha256 }, Buffer.from(password)); return encrypted.toString(base64); }5. 完整登录流程实现5.1 收集必要参数除了加密密码Facebook登录还需要其他一些参数。这些参数大多可以从页面中提取jazoest藏在表单里的校验值lsd防CSRF tokencsr页面生成的随机值dyn动态加载参数这些参数虽然看起来复杂但很多其实可以直接从HTML中提取固定值对登录影响不大。5.2 构建登录请求收集完所有参数后就可以构建POST请求了。关键是要注意参数顺序和编码格式。Facebook使用的是标准的application/x-www-form-urlencoded格式。一个典型的登录请求体如下lsdxxxxxjazoestxxxxxencpassxxxxxlgndimxxxxx...5.3 处理登录结果成功登录后服务器会返回302重定向并设置一系列cookies。这些cookies就是后续请求的身份凭证需要妥善保存。特别要注意检查是否有checkpoint验证这种情况通常意味着登录行为被判定为可疑需要额外的验证步骤。6. 实战中的注意事项在实际项目中有几个坑需要特别注意密钥有效期publicKey并不是永久有效的通常几个小时就会失效。所以不能长期缓存每次登录前都应该重新获取。请求频率控制Facebook对频繁登录尝试有严格的限制建议控制请求频率必要时使用代理IP轮换。用户代理使用真实的浏览器User-Agent很重要太简单的UA容易被识别为机器人。Cookie处理登录成功后返回的cookies要完整保存缺少任何一个都可能导致后续请求失败。异常处理要做好各种异常情况的处理比如验证码、账号锁定等。7. 加密方案的安全启示Facebook的这套加密方案给我们开发自己的登录系统提供了很好的参考前端加密即使使用HTTPS对敏感数据额外加密也是好习惯。密钥分离加密密钥与业务服务器分离降低泄露风险。设备指纹像lgndim这样的参数可以帮助识别客户端设备。时效控制短期有效的加密密钥增加了安全性。逆向分析这些大型网站的登录机制不仅能帮助我们开发更好的自动化工具更能学习到一流的安全实践。当然所有技术都应该用在合法合规的领域切记不要滥用。

更多文章