你肯定遇到过这种情况。想订阅一份 newsletter,Google 让你找出所有自行车。你眯着眼看图片。漏掉一个像素。然后得到一张新的网格图,这次是摩托车,你开始怀疑自己到底是不是机器人。
这就是 reCAPTCHA。它确实能用,某种程度上。但它同时会在每个使用它的页面上从 google.com 加载一个 JavaScript 包,把你的浏览行为发送到 Google 的风险评分 API,而且几乎每次做 cookie 合规审计都会被标记出来。
Orkestr 使用的验证码方案是 Altcha。自托管,无第三方 JS,无 Google,无行为追踪。用户看不到拼图题。只有一个复选框,浏览器安静地显示"验证中……",同时在后台做一些数学运算。整个过程大约一秒钟。
这篇文章会解释为什么我们在众多知名方案中选择了它。如果你正在寻找 Google reCAPTCHA 的替代品,并且你关心 GDPR,这是我们会推荐的道路。
对于中低流量的表单场景(注册、联系、评论、登录),如果你不是处于持续的机器学习驱动的攻击之下:自托管 Altcha 是正确的选择。无第三方调用,无 GDPR 文档负担,无让用户反感的拼图题,一个从自己域名加载的轻量小部件。
对于处于活跃攻击之下、由复杂攻击者操控的超高流量公开页面(电商结算、抢票、大型社交平台),你可能仍然需要带有行为 ML 的托管服务。Altcha 的工作量证明方案提高了每次请求的成本;但在互联网规模下,真正的僵尸农场还是能承受这个开销的。
"中低流量表单"就是大部分互联网的样子。对大多数人来说,Altcha 是赢家。
| Google reCAPTCHA v3 | hCaptcha | Cloudflare Turnstile | Altcha(自托管) | |
|---|---|---|---|---|
| 数据离开你的源站 | 是(google.com) | 是(hcaptcha.com) | 是(cloudflare.com) | 否 |
| 行为追踪 | 大量 | 中等 | 少量 | 无 |
| JS 包大小(gzip) | 300+ KB | 250+ KB | 85+ KB | 34 KB,来自你的源站 |
| 用户拼图 | 经常 | 经常 | 很少 | 从不 |
| GDPR 合规 | 美国子处理方 | 美国子处理方 | 美国子处理方 | 无,数据留在你的服务器 |
| 可自托管 | 否 | 否 | 否 | 是 |
| 费用 | 免费 + 付费套餐 | 免费 + 付费套餐 | 免费 | 免费(你的 CPU) |
"数据离开你的源站"这一行就是整个问题的核心。其他所有列都由此衍生而来。
reCAPTCHA v3(所谓的"隐形"版)其实并不是验证码。它是一个行为指纹采集库,返回一个介于 0(疑似机器人)和 1(疑似人类)之间的分数。这个分数来自 Google 分析你的浏览器、IP、鼠标移动、cookie,以及关键的是——如果你碰巧登录了——你的整个 Google 账户状态。
对于大规模欺诈检测来说,这确实是一个好功能。但对于一个欧盟企业来说,这就是法律和声誉风险,因为你网站上的每个表单都变成了 Google 的数据采集端点。Schrems II 裁决已经把每一次向美国广告技术公司的跨境数据传输变成了每个工具的合规问题。reCAPTCHA 正是这类工具。
2026 年 4 月 2 日之后,合规状况变得更加严峻。Google 将 reCAPTCHA 从数据控制方重新归类为数据处理方——这听起来像 Google 内部的一个细节,但实际并非如此。欧盟运营商现在必须为每一次 reCAPTCHA 调用承担 GDPR 合规的全部责任:与 Google 签署 DPA,在你的隐私政策中明确记录法律依据,并由你的团队处理所有数据主体请求。数据仍然流向美国服务器。合规负担并没有减少,而是转移到了你的桌子上。
欧盟的 DPO(数据保护官)们用不同方式问着同一个问题:如果你登录页面上的 JavaScript 不受你控制,那谁来控制?这个问题值得好好想想。
Turnstile 是行业对 reCAPTCHA 疲劳的回应。它免费,用户体验好(大多数用户只看到一个复选框,而不是拼图题),而且 Cloudflare 在数据采集方面的透明度比 Google 高得多。如果你不在欧盟,也不关心 CLOUD Act 的暴露风险,Turnstile 是一个不错的选择。它是这里提到的方案中第二好的。
不过,对于面向欧盟的部署平台来说,每一个美国子处理方都是 DPA 中的一行,欧盟买家会逐行阅读。我们希望验证码成为自己源站上的东西,而不是别人服务器上的东西。Turnstile 无法实现这一点。
Altcha 用"让机器人为之付出代价"的模式替代了"给用户评分"的模式。这就是工作量证明(Proof of Work)。
服务器生成一个随机盐值(salt)、一个随机数(nonce)和一个目标前缀(target prefix),用只有服务器知道的 HMAC 密钥对整个数据包签名,然后交给浏览器。一个 Web Worker 不断迭代计数器,将计数器值与随机数结合,每一步运行 PBKDF2-SHA256,直到派生出的密钥以目标前缀开头。当找到匹配的计数器时,服务器会收到挑战和答案,验证 HMAC,验证前缀匹配,然后接受表单。
整个过程在一台现代笔记本电脑上大约需要一秒钟。人类完全感觉不到。而一个试图每秒钟每个 IP 提交一万次表单的僵尸农场,突然必须为每次提交消耗实实在在的 CPU 资源。
没有第三方。挑战端点就在你的域名上。小部件的 JavaScript 从你的源站加载。HMAC 密钥永远不会离开你的服务器。你的子处理方列表上没有什么需要添加的——因为根本就没有子处理方。
集成工作很小。一个新端点,一个 HMAC 环境变量(openssl rand -hex 32),一个用于小部件的 React 组件。有两件事容易被忽略,都值得指出来。
我们的服务使用了 Bunny CDN 做 SSL 和边缘缓存。第一次接入 Altcha 时,我们遇到了一个奇怪的故障模式:真实用户首次提交时会间歇性地收到"验证码已使用"的错误。
原因事后看其实很明确。CDN 在缓存 GET /api/altcha/challenge 的响应。两个不同的用户拿到了同一个签名的挑战,第一个用户提交后消耗掉了它(通过重放保护机制),第二个用户就会收到 400 错误。
修复方案只需要一个响应头:
@router.get("/altcha/challenge")
async def get_challenge():
challenge = mint_challenge(hmac_key, cost=5000)
return Response(
content=challenge.json(),
media_type="application/json",
headers={"Cache-Control": "no-store"},
)
如果你使用任何 CDN,务必设置这个头,否则你会花一整个下午调试为什么验证码在生产环境大规模失灵,而在本地却工作正常。
验证码面临的重放攻击思路很直接:捕获一次合法的提交,然后重放多次。大多数官方的 Altcha 库(Django、.NET 等)已经把重放存储内置了,所以在你自己造轮子之前先检查一下。我们基于 FastAPI 做了自己的集成,因此需要自己加一个。使用基于验证后的 solution hash 的 Redis SETNX:
# 如果 key 被成功设置返回 True(首次使用),如果已存在返回 False(重放)
is_first_use = await redis.set(
f"altcha:used:{solution_hash}",
"1",
nx=True,
ex=600, # 10 分钟,安全地长于挑战的 TTL
)
if not is_first_use:
raise HTTPException(400, "captcha already used")
一个内存中的字典无法在部署后存活,也无法跨工作进程扩展。Redis 可以。Postgres 也可以。选一个持久化的方案,设置一个比挑战过期时间更长的 TTL,就搞定了。
我们还为每个环境使用独立的 HMAC 密钥,这样开发环境泄露不会影响生产环境的挑战伪造。理由和把测试 Stripe 密钥与生产密钥分开是一样的。
我们想诚实地说明它的局限,因为这些局限是真实存在的。
你正在遭受复杂机器人运营商的主动攻击。一个拥有云资源的真正僵尸农场可以承受工作量证明的成本——对机器人来说,代价只是边际 CPU 成本。PoW 提高了门槛,但并不能对决心坚定的攻击者设置上限。如果你曾经因为竞争对手爬取而不得不从网站上撤下定价数据,你需要的是行为 ML,而不是一道数学题。另外,Altcha 也支持 Argon2id 和 Scrypt 作为内存硬化的替代方案(替代 PBKDF2),它们能够抵抗 GPU 和 ASIC 加速,缩小消费级设备和僵尸农场之间的差距——虽然不是银弹,但值得了解。
你的用户使用非常低端的设备。现代笔记本电脑上一秒能解完的问题,在一台五年前的廉价手机上可能需要四秒。如果你的受众是发展中市场的消费级移动用户,在部署之前先做基准测试。
你无法运行 Redis(或其他等效方案)来做重放保护。没有单次使用强制机制的验证码只是做做样子。如果你的托管方案不允许添加键值存储,先解决这个问题,再回来继续。
对于所有其他场景——SaaS 注册表单的长尾、内部管理工具、联系表单、评论区、账户恢复流程——在 2026 年,Altcha 是比 reCAPTCHA 更好的默认选择。
Altcha 真的免费吗?
是的。它采用 MIT 许可证开源。代码库在 github.com/altcha-org/altcha。成本是验证服务器消耗的 CPU(可以忽略不计)和客户端计算(每次提交大约占用一个核心一秒钟)。
我需要运行一个独立的 Altcha 服务器吗?
不需要。Altcha 是一个协议加一个小型客户端库。你只需要在现有后端上添加两个端点:一个用于生成挑战,一个用于验证。没有"Altcha 即服务"这一说——除非你选择使用他们的托管方案。
Altcha 在没有 JavaScript 的情况下能工作吗?
默认流程需要 JavaScript(Web Worker 是工作量证明的运行环境)。Altcha 也支持服务端模式,可以在表单提交时验证预先计算好的挑战,这对无障碍工具很有用。大多数场景不需要这个功能。
从 reCAPTCHA 切换到 Altcha 会破坏我的表单分析吗?
只有在你的分析中把 reCAPTCHA 的"人类评分"作为连续信号使用时才会。如果它只是二元的通过/失败门槛来控制表单提交,切换是无感的。
我能在静态网站上使用 Altcha 吗?
你需要一个地方来生成和验证挑战。一个无服务器函数就够了。用大约 30 行 Python 代码就能实现一个小型无服务器函数来处理这件事。
验证码是那种看起来已经解决了的问题——直到你读了隐私政策。大多数团队选择 reCAPTCHA 只是因为它是默认选项,而不是因为他们评估过它。如果你是一家欧盟企业,你几乎肯定没有评估过它。你的 DPO 最终会,而这场对话不会太愉快。
我们选择 Altcha 是因为它是唯一能让整个流程留在自己源站上的方案。你可以在你已有的任何后端上运行同样的东西。也就是几百行代码和一个 Redis 键前缀而已。
如果你也在意你的技术栈中还有哪些美国服务在悄无声息地运行,Vercel 2026 年 4 月泄露检查清单是一份有用的参考读物。
——
一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。