科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件用Python的hashcash 打击垃圾邮件

用Python的hashcash 打击垃圾邮件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文讲解如何利用Python下的hashcash 打击垃圾邮件,还将介绍这项技术在邮件过滤方面的应用,并将提供它在其他一些方面的应用。

作者:51cto.com整理  来源:51cto.com整理  2007年9月15日

关键字: 软件

  • 评论
  • 分享微博
  • 分享邮件
这会起什么作用?

生成一个 20-比特的戳记只需要几秒钟的时间。当您一天中只发送几十封电子邮件时,这个代价并不大。但是,对那些想要发送数百万消息的垃圾邮件制造者来说,不能容忍每条消息使用额外几秒的 CPU 时间。一天之中只有 86,400 秒。即使垃圾邮件制造者利用植入木马(trojans)的僵尸(zombies)的技术,需要使用具体的 hashcash 戳记至少也会减少那些僵尸进程的发出量。当然,校验一个戳记所需的时间只是一秒的一小部分。

另一方面,向您自己的 MUA 添加 hashcash 生成和校验对其他所有人没有任何负面影响(不像其他一些反垃圾邮件方法)。对那些不使用该协议的接收者而言,这些只是一个他们很容易忽略的附加头文件。对那些没有添加 hashcash 戳记的发送者而言,检验 X-Hashcash: 的接收者不用校验任何内容。如果发送者没有添加戳记,那么您的境况不会因为进行检验而变得更糟;也不会因此变得更好。

一个好的 MUA 或者垃圾邮件过滤系统可以将拥有合法 hashcash 戳记的电子邮件列入白名单(whitelist)。SpamAssassin 甚至更巧妙地为更多合法 hashcash 比特提供了更高的 +ve 分数。我认为,将基于 bashcash 的方法应用于白名单是对 TMDA 等交互式质询系统的改进 —— 质询消息在返回时不会丢失,发送者不会忘记响应质询。质询响应就在原始消息之中(作为一个 hashcash 戳记)。

hashcash 的其他应用

hashcash 对非交互式质询最为实用。不过,没有理由使得它不能同样用于交互式上下文中。随着更多工具增加了对 hashcash 的支持,尤其是 Mozilla 套件等多用途应用程序,在交互式和非交互式条件下使用 bashcash 都同样变得更加简单。

例如,如果 Thunderbird 邮件工具得到了进行 hashcash 计算的 API 调用,那么它应该直接让它的同属工具 Firefox Web 浏览器用与生成 hashcash 戳记的 API 去响应交互式质询。

什么是 Wiki?

Wiki 是“可以运转的最简单的在线数据库”。它支持设计用于动态创建新页面和页面之间交叉链接的超链接和简单文本语法处理。

Wiki 是服务器软件,允许用户使用浏览器自由地构建和 编辑 Web 页面的内容,提供了一种“开放编辑”服务,从而促生了一种不同寻常的群组通信机制。它不仅允许所有用户编辑页面的内容,还允许用户编辑对页面或者站点做出贡献的组织。

保护 Wiki

Wiki 有时会遭遇到与垃圾邮件十分类似的破坏,bashcash 在非电子邮件上下文中似乎是一个不错的解决方案。由于 Wiki 通常开放给任何人进行编辑,所以 Wiki 社区的灾难之一是 Wiki-crawling 破坏程序,它们向 Wiki 站点添加一些无关的商业链接。

我帮助维护的一个 Wiki 最近不断遭到恶意破坏,迫使我们做出了有些不受欢迎的回应,要求所有张贴者拥有一个用户帐号。这些帐号都是在一视同仁的基础上给出的,并根据自动使用电子邮件发送的质询来返回一个证明已经收到随机密钥的消息。不过,要求使用这样的帐号从根本上说与 Wiki 精神是相违背的。

添加 hashcash 质询并不能防止对 Wiki 站点的自动破坏,但是它可以使破坏行为变得更慢。如果破坏一个站点需要的时间是很多秒,而不是一秒的一小部分,那么检索 Wiki 找出无用信息就不那么引人注目了。实际上,我认为在这种应用中,使用大于 20-比特的传输率是一个好主意。也许 24 比特或 28 比特是合理的负荷(已经登录的用户仍然可以避开它)。

您可能会认为,在接受 Wiki 编辑时,普通的时间延迟会有类似效果,不过这种思维方式中有一个漏洞。破坏者可以并行化其破坏行为 —— 例如,如果每个站点添加了 5 秒的延迟,那个破坏者可以利用这 5 秒钟的时间来开始对其列表上的其他 Wiki 进行修改。通过要求保证有效 CPU 的利用率,比如使用 bashcash,破坏者再也不能并行地进行破坏。

Wiki 质询可以是交互式的,也可以是非交互式的。站点在将用户引导到实际的编辑屏幕之前,可以直接将用户引导到一个质询屏幕。可以生成一个随机资源来作为这个保护屏幕的质询。

不过,更好的方法是使这项要求具有非交互性。例如,在一个已有的 Wiki 系统中,可以使用与下方所示类似的 URL 来编辑某个资源:

http://somewhere.net/wiki?action=edit&id=SomeTopic

在一个假定使用 bashcash 进行保护的 Wiki 中,可能需要使用不同的 URL,比如:

http://somewhere.net/wiki?stamp=1:24:040928:SomeTopic:edit:KG4E9PaK2VLjKM2Z:0000Zbrc

在允许编辑之前,Wiki 服务器可以校验该戳记。不过,进行编辑不需要创建一个帐号和透露任何个人信息。double spending 和(可能持续时间较短)过期校验进一步为真正要进行编辑的行为提供了保证。对我而言,生成上面的 URL 并不难,使用下面的命令即可:

hashcash -mCb 24 -x edit SomeTopic

不过,通常,为了确保更少的延迟,Web 浏览器可能会选择在后台生成类似的戳记。例如,当我正在读取资源时,上述 URL 可能已经创建在高速缓存中:

http://somewhere.net/wiki?SomeTopic

或许还将缓存其他一些编辑戳记,将它们用于当前 Wiki 页所链接的页面。

检验 CPU 资源

hashcash 的一个交互式应用可能是用于分布式处理任务中。一些项目(比如 Great Internet Mersenne Prime Search(GIMPS))和 SETI@home 及其任务(比如蛋白质折叠和密码方面的难题)有时会借用大量的志愿者机器,这里只列出了其中少数项目和任务的名称。每个志愿者都只需要下载一些代码,并将其作为一项大任务的一部分来运行,然后将中间计算发回中央服务器即可。这些工作是对空闲 CPU 周期的极好利用。

我所知道的所有分布式任务几乎都允许任何人加入。不过,不难想像,对于有协同要求的任务而言,如果一个节点不能在期望的时间段内完成其任务,那么这个行动迟缓的节点对整体计算造成的损害要比它所做贡献多一些。

在这种情况下,应该要求每一个参与节点都有最小限度的 CPU 速度。虽然使用具体类型的计算来检验速度更为精确,不过,hashcash 还提供了一个相对通用的 CPU 基准。SHA-1 是一种非常典型的数学计算。如果参与节点已经安装了 hashcash(而不是一些定制的软件工具),那么,对 hashcash 质询的回答就可以作为一种“必须达到某种高度才能登堂入室(you must be this tall to enter this ride)”风格的校验。

校验 CPU 能力的方法是,要求在短期间内得到高比特值。只有足够快的 CPU 才能回答这个质询。为此,必须半交互式地提供资源名。否则,参与者完全可以迟签他们的日期戳的日期,制造出创建速度很快的假象。

例如,一个快速的 Pentium III 或者 G4 可以在不到一秒钟之内生成一个 20-比特的戳记,但是 Pentium-II 或者 G3 做不到。我们可以假定一个 32-比特的质询,试运行的候选机器必须在一个小时之内回答它。请求者可能会发一封电子邮件,说:“向我发送一个质询”;协同服务器作出响应:“时间是 040927124732;质询资源是 a37tQk。”如果服务器在当天下午的 1:47 之前得到了一个正确的散列,那么该请求者将获得访问该资源的资格。

显然,我所建议的协议不能确保在每个节点上都能真正地完成工作。即使是最快的机器,也可能会出现断电的意外情况。用户可能会改变他们运行分布式软件的想法。不过,至少可以证明其具备似乎可信的资格。

通用的 hashcash 以及我的贡献

从 hashcash 概念整体来看,具体域和分隔符的使用从某种程度上说是任意的。实际上,hashcash 版本 0 使用了与版本 1 不同的域。这些选择都很好,不过,我认为“实际的 hashcash”只是某个家族的一名成员,我们可能会称这个家族为“通用 hashcash”。也就是说,只要给定任何质询字符串,都可以合理地提出以下要求:“给我一个后缀,一旦 challenge+suffix 被散列,它将生成 b 比特的碰撞”。真正的 hashcash 只不过是这种通用质询的一个实例。

现在,确实存在过于通用的问题。创建很多不兼容的、近似 bashcash 的协议实际上对谁都没有好处。例如,有一个“hashcash”的 Python 实现,使用了一个与 bashcash 有一点类似的质询协议(可能对加密价值而言也是如此),但是几乎不能使用它生成 hashcash 戳记。

所以,我决定编写一个真正适应的 bashcash 的 Python 实现,它甚至可以接受与用 C 编写的 hashcash 工具大致相同的命令行开关(不过,可能最为实用的是作为一个导入模块用于其他应用程序)。即使是在得到了 Psyco-ization 的帮助(只是一点点)的平台上,Python 版本最快运行也要比优化的 C 版本慢 10 倍。不过与 C 相比,它在灵活性方面依然可以胜出。

除了正确无误,我的 hashcash.py 模块还提供了一个内部函数 _mint() 以及一个公共函数 mint()。后者生成真正的 hashcash 版本 1 戳记。那是您应该使用的。

不过,前者,即 _mint(),完成了寻找 generalized hashcash 后缀的底层工作。您可能不应该使用它,但是,如果您想要使用它(并且保证您会小心使用它),它就在那里,您可以使用。

在不同寻常的上下文中,bashcash 的变种可能很实用。无论如何,我希望 C 工具有类似的开关,即使是在 man 页中有关于您为什么不应该那样做的危险警告,它们也能够找到通用的 hashcash 后缀。我们电脑黑客喜欢深入到事物内部。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章