V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
greensea
V2EX  ›  分享创造

wCaptcha, 一个基于工作量证明的 CAPTCHA

  •  
  •   greensea ·
    greensea · 130 天前 · 4419 次点击
    这是一个创建于 130 天前的主题,其中的信息可能已经有所发展或是发生改变。

    CAPTCHA 就是所谓的验证码,不过这个基于工作量证明的验证码可以不要求用户进行操作,在后台就可以默默地完成。

    这个验证码的核心在于,用工作量证明的方式取代了要求用户进行一些操作,来证明客户端是一个人类。不过这个验证码其实并不能区分客户端是不是人类,它的主要目的是防止大量的恶意请求,比如爆破用户名密码、爬虫之类。

    对于一个普通用户来说,花几秒钟的时间做一个计算,然后再提交表单,这是完全可以接受的,可是对于爬虫或者登录接口爆破之类的机器人来说,如果每发一个请求就要花两三秒的 CPU 时间,这就完全不可接受了。

    工作量证明算法使用了不可并行加速的算法,也就是说,显卡加速是废的,多核计算也是废的(除非同时对一个接口发送多个请求,但这样的请求是非正常的,很容易过滤掉)。

    网站在这里: https://wcaptcha.pingflash.com 如果担心数据安全,可以直接用源码私有化部署。

    至于算法细节之类的东西,都可以在网站上找到,我就不在这里废话了。

    46 条回复    2023-02-20 16:07:28 +08:00
    oott123
        1
    oott123  
       130 天前
    不如说说在浏览器端你这个提交一次要算多久,在 native 平台下要算多久
    xiangyuecn
        2
    xiangyuecn  
       130 天前
    禁止掩耳盗铃😂
    greensea
        3
    greensea  
    OP
       130 天前
    @oott123 浏览器用 WASM 计算,速度是原生的 1/6 。计算量是可调整的,于是在实践中可以在用户开始填写表单的时候就进行计算,花个 6s 出结果,这样对于机器人来说,每个请求就要花费 1s 的 CPU 时间
    shortmund
        4
    shortmund  
       129 天前
    抖个机灵,这个方案不环保😂
    sunshower
        5
    sunshower  
       129 天前 via Android
    标题差点以为用验证码挖矿了
    zenxds
        6
    zenxds  
       129 天前   ❤️ 2
    证明客户端是一个人类?跑一个 headless 浏览器就绕过了。另外黑产的机器性能很多都是非常好的,最后拦不住黑产反而降低了普通用户的体验,还容易被误解为挖矿
    mxT52CRuqR6o5
        7
    mxT52CRuqR6o5  
       129 天前
    对于单个验证码是不能并行,但我可以获取多个验证码去并行
    greensea
        8
    greensea  
    OP
       129 天前
    @sunshower 其实我也是受另一个 CAPTCHA 的启发,那个 CAPTCHA 用纯 hash 的方式做计算量证明,我有点怀疑它在挖矿,不过我也没细看它的源码就是了。
    @zenxds 用 headless 不如直接上原生程序,速度更快。另外这个验证码的目标是过滤掉那种需要大量发送请求的用户,对于其他类型的恶意用户是无能为力的
    greensea
        9
    greensea  
    OP
       129 天前
    @mxT52CRuqR6o5 是的,这是一个弱点,不过在具体实践上可以做点额外的工作。

    比如爆破某个账户,可以根据账户名,限制同一时间只能提交一个工作量证明,工作量证明提交之后,此前产生的所有工作量证明问题直接失效,这样就没法针对这个账户做并发请求了。

    这个验证码其实也就是一个很基础的框架而已,最好还是结合业务的实际情况来适配一下,效果才好。
    Jirajine
        10
    Jirajine  
       129 天前
    1/6 wasm 的性能还这么差啊
    这种纯计算 效率至少不应低于现代虚拟化技术的 80%到 90%。
    IvanLi127
        11
    IvanLi127  
       129 天前 via Android
    这个方案配合业务做成无感知的,用户体验就挺好。要是能让 wasm 和 native 速度上相当就好了,不然感觉有点事倍功半?哈哈
    patrickyoung
        12
    patrickyoung  
       129 天前 via iPhone
    上一个这么干的已经凉了,叫 coinhash 还是什么的挖矿验证码
    mcfog
        13
    mcfog  
       129 天前 via Android   ❤️ 3
    captcha 其实是个缩写 t 是图灵的 t
    把工作量证明的 w 放前面这个名字有点黑色幽默
    毕竟能跑得动工作量证明的那么多计算的,反而是机器
    FakerLeung
        14
    FakerLeung  
       129 天前
    太不环保了。。。
    greensea
        15
    greensea  
    OP
       129 天前
    @Jirajine @IvanLi127 我也没想到 wasm 速度居然差这么多,测试下来也是出乎我的意料。wasm 这边是直接丢进 gmp-wasm 里面计算的,具体的计算也就是连续几百万次平方取模,看起来也没什么复杂的东西会导致两边的性能差距。现在我觉得最大的可能是原生代码可以直接利用 CPU 的指令集特性,而编译成 wasm 的 gmp 只能用乘法器和除法器死算
    c0xt30a
        16
    c0xt30a  
       129 天前
    除非你的网站是无可替代的,不然用户真的没必要忍受 captcha 。这种在用户的浏览器上运行的 '挖矿' chapcha 尤甚。

    昨晚在 techmania 购物跳转到登陆页面准备付款的时候碰到了三次 captcha 验证,然后我直接换别的网站下单了,虽然贵了几十瑞郎。
    Sainnhepark
        17
    Sainnhepark  
       129 天前 via Android
    那为啥不直接采用延时的方式来验证呢?提交 captcha 后,服务端隔一段时延发送回确认消息,这样也不需要消耗客户端的 CPU 。
    IvanLi127
        18
    IvanLi127  
       129 天前 via Android
    @Sainnhepark 用延迟的话,那拿几个代理 ip 并行请求,不就绕过去了?
    kisshere
        19
    kisshere  
       129 天前 via Android
    搜索引擎蜘蛛可能会认为你在恶意挖矿
    maggch97
        20
    maggch97  
       129 天前 via Android
    @Sainnhepark 哈哈,你说的太对了。我感觉可以结贴了


    @IvanLi127 两个做法是完全等价,如果有问题,那也是相互都有的问题
    jonathon523
        21
    jonathon523  
       129 天前 via Android
    这种实现是不是感觉还不如 Cloudflare 的检测浏览器是否异常的验证码呢?感觉反而会让用户体验更差。
    Sainnhepark
        22
    Sainnhepark  
       129 天前 via Android
    @maggch97 不,并不等价,我觉得 18 楼说得有道理。比如我设定时延是 3s ,那么拿 5 个 IP 做代理,通过 captcha 的平均时间就变成了 0.6 秒,IP 越多通过 captcha 的平均时间就越快。但 OP 的这个思路就不会存在这个问题,IP 越多服务器的 CPU 占用就越高,直到满载。
    greensea
        23
    greensea  
    OP
       129 天前   ❤️ 2
    统一回复一下大家比较关注的点:

    1. 关于 CAPTCHA 太多影响体验的问题,其实这个 CAPTCHA 是可以在后台运行的,初衷之一就是为了解决需要用户交互的问题,用户开始填表单的时候就开始计算,等用户填完表单了也算完了,这时候直接提交就行,不需要输个验证码或者选个图片之类的麻烦操作

    2. 这个 CAPTCHA 的核心思路是,每个请求都必须消耗一定的 CPU 资源,如果想要发起很多请求,那么就要消耗很多 CPU 资源,攻击者的成本就上去了

    3. 这个 CAPTCHA 也不是什么银弹,可以一劳永逸地解决人机验证问题,它可以应付的情况仅限于恶意攻击需要发起大量请求的情况,使用场景还是有一定限制的
    mason961125
        24
    mason961125  
       129 天前 via Android
    coinhive 都倒闭几年了
    learningman
        25
    learningman  
       129 天前
    认真的吗,Ryzen 3600 跑你的 demo 差不多得要 2 分钟
    cyp0633
        26
    cyp0633  
       129 天前 via Android
    @learningman 不正常吧,我在手机浏览器上跑都不用五秒
    oott123
        27
    oott123  
       129 天前 via Android
    1/6 太差了,至少也要 1/2 才可以接受吧。考虑到用户可能用的是个破手机,而且你的 pow 有效期不宜太长,没法真的在开始填表的时候算——否则用户提交上去的时候就过期了。
    Aloento
        28
    Aloento  
       129 天前
    我的评价是你不如拿用户的资源干点正事
    wyf001912hp
        29
    wyf001912hp  
       129 天前 via Android
    之前我用 coinbase 还是 coinhash ,总之是一个挖 XMR 的验证码,和楼主的想法完全一致。后来谁挂这个验证码,Google 就给哪个网站标红,最后还跑路了。
    WuSiYu
        30
    WuSiYu  
       129 天前
    之前也想过这种,不过还是不太现实,这个计算虽然单个没法并行,但也不需要,完全可以攒一堆然后批量跑。
    用 GPU 一秒估计能跑几千几万个,甚至因为这个计算的访存压力极小,都能跑满理论 TOPS 性能,相比没有这个工作量证明,爬虫仅仅是多了个 GPU 的成本
    lslqtz
        31
    lslqtz  
       129 天前 via iPhone
    1. 思路很不错, 通过提高验证成本来提高机器人的并发难度, 不过核心变成了反破解. 对于大规模批量采集, 会显著增加采集成本, 提高采集时间.
    2. 理想情况下, 无论算力如何, 都应该具有相似的时间消耗, 即计算量需要是可变的, 以防止较好的硬件非常快的取得结果.
    3. 关于环保问题, 顺便挖个矿其实也是非常可取的.
    4. 验证码的并发限制是个很基本的东西, 配合 IP 库判定代理可以取得更好的效果.
    leonshaw
        32
    leonshaw  
       129 天前   ❤️ 1
    工作量浪费了,不如直接改成用户支付一定虚拟货币才能登录
    learningman
        33
    learningman  
       129 天前 via Android
    @cyp0633 应该是 edge 节能模式的问题? CPU 只跑了 10%左右
    lambdaq
        34
    lambdaq  
       129 天前
    计算量我觉得太费电了。。有没有不费电但是需要 2G 内存的。。。?
    Showfom
        35
    Showfom  
       129 天前
    @patrickyoung #12 叫 Coinhive 已经倒闭了
    iqoo
        36
    iqoo  
       128 天前
    1/6 太低了,其实有办法 100% 的。
    xenme
        37
    xenme  
       128 天前 via iPhone
    之前看到一个类似的,客户端计算耗时较长,服务端验证很快,主要是防爆破,不一定要挖矿
    greensea
        38
    greensea  
    OP
       128 天前
    继续回复大家关注的点:

    1. 关于 GPU 加速的问题,虽然说可以用 GPU 对多个工作量证明进行并行计算,但是平摊下来每条流水线的速度估计会很慢(关于这一点我没证实过,只是纯推测),这样就没法在一定时间内算出结果了。另外之前也回复过了,对于多个请求进行并发计算,这验证码是没法直接防住的,需要根据具体业务做一点额外的工作。

    2. 关于是否能有不消耗 CPU 而是消耗内存的算法。这种算法肯定是有的,不过我还没有研究过,过段时间可以翻一翻论文找找。

    3. 大家别看到工作量证明就想到挖矿哈,客户端算个几秒钟不算什么消耗嘛,该消耗的 CPU 还是该消耗的嘛,就像谷歌一次就要排放多少克碳,可我们该搜索也还是要搜索嘛。传统的需要交互的验证码,虽然不用消耗 CPU ,可却消耗了用户的生命不是嘛
    greensea
        39
    greensea  
    OP
       128 天前
    @iqoo 愿闻其详,wasm 已经是我能找到的在浏览器里面计算最快的方法了
    hanbing135
        40
    hanbing135  
       128 天前
    没太看懂
    iqoo
        41
    iqoo  
       127 天前
    @greensea PoW 有很多方案,直接用浏览器原生的 Crypto API 也可以。
    devliu1
        42
    devliu1  
       126 天前
    https://github.com/mCaptcha/mCaptcha 另一个开源的 PoW Captcha 方案
    greensea
        43
    greensea  
    OP
       126 天前
    @iqoo 新年好。我看了一下 Crypto API ,它提供的主要是密码学相关的高级函数,而这个验证码的计算只是简单的乘法取模,没法使用 Crypto API 进行加速。
    PoW 是有很多方案,但是这里需要选择一个可以抵抗并行加速的方案,否则攻击者用显卡就可以轻松绕过了。

    @devliu1 新年快乐。实际上我就是受 mCaptcha 的启发,wCaptcha 和它的思路是一样的。区别在于,mCaptcha 的方案是普通的连续哈希,这就给显卡加速留下了可乘之机。
    不知道它现在有没有更新算法,现在 mCaptcha 的网站似乎挂了,回头我再去看看它有没有更新。
    Thiece
        44
    Thiece  
       122 天前
    @greensea
    「工作量证明算法使用了不可并行加速的算法」是指 SIMD 或者 MIMD 吗?
    greensea
        45
    greensea  
    OP
       122 天前
    @Thiece 不是,具体算法就是计算连续平方取模,因为后面的计算依赖前面的结果,所以没法并行加速。类似连续哈希
    RadishWind
        46
    RadishWind  
       98 天前
    赞, 最近在学习 web3, 发现之前 coinhive 的验证码用的好像就是类似的技术 刚好找到了楼主的帖子
    关于   ·   帮助文档   ·   博客   ·   nftychat   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4889 人在线   最高记录 5634   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 06:54 · PVG 14:54 · LAX 23:54 · JFK 02:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.