levels.fyi 如何编码 API 响应?

问题描述 投票:0回答:2

我在浏览 levels.fyi 时注意到一些有趣的事情。当我访问显示工资列表的页面时,返回工资数据的 API 响应似乎经过了哈希处理。例如,如果您致电:

GET https://api.levels.fyi/v3/salary/search?countryIds[]=197&offset=10&limit=50&sortBy=offer_date&sortOrder=DESC&jobFamilySlug=software-engineer

响应如下所示:

{
    "payload": "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"
}

我相信前端和后端都有一个用于散列和解码响应数据的密钥。如果可能的话,我想在我自己的 API 上实现类似的东西并了解它是如何工作的。

javascript security
2个回答
0
投票

他们的实施

您是正确的,有一个密钥用于加密和解密 JSON 有效负载。好吧,没那么“秘密”,因为关键在于下载到浏览器的JS。我认为他们这样做是为了让通过 API 抓取网站内容变得更加困难。

加密的有效负载以 Base64 编码发送(因此获取内容的第一件事是将其转回未编码的字节序列)。

如果您查看网站上的

commonUtils.js
文件,您将找到一个执行解密的函数(只需搜索
CryptoJS.AES.decrypt
)。解密过程是使用 MD5 对“秘密”字符串进行散列,然后从散列的一部分导出密钥。然后使用该密钥对已解码的有效负载进行 AES-128 解密。来自此的明文是 zlib 压缩流。

因此,获得标准 JSON 响应的最后一步是对流进行膨胀,并且结果是可读的。

{
 "total":1000,
 "hidden":0,
 "rows":[
  {
   "uuid":"b0b851a1-ba7b-49ab-8190-6bf8aec0aa21",
   "title":"Engineer",
   "jobFamily":"Software Engineer",
...

你如何能做同样的事情

首先,选择一个用于加密有效负载的密钥。以浏览器中运行的 JS 代码可访问的某种方式向浏览器提供密钥。

当您想要发送有效负载时,请将有效负载作为一个整体进行压缩(该站点使用 zlib deflate,从性能和适用性的角度来看这是明智的)。然后使用您的“秘密”密钥进行加密(他们进行了一些推导,从而失去了针对实际加密攻击的密钥的一些安全性,但他们没有安全地处理密钥,因此这并不重要)。最后,Base64 编码并发送响应(他们将其放入 JSON 响应中,这也是一个好主意)。

在浏览器中,相反:获取 JSON 有效负载;从 Base64 解码;根据需要建立您的密钥;使用密钥解密解码后的有效负载;解压缩结果,您就可以得到返回到调用函数的响应。

levels.fyi 似乎使用静态字符串作为其加密密钥,但理论上,如果您愿意,您可以定期生成新密钥。


0
投票

我想知道这个方法还有效吗?

© www.soinside.com 2019 - 2024. All rights reserved.