6

IMAP 消息有一个UID我们都为之高兴的。但是,我试图弄清楚如何为 POP3 邮件生成唯一 ID,但遇到了麻烦(hotmail.com 等旧系统只允许 POP3)。

当 POP 会话打开 maildrop 时,发送给客户端的可用消息是固定的,并由该会话本地的消息号标识,或者可选地,由 POP 服务器分配给消息的唯一标识符标识。这个唯一标识符对于 maildrop 是永久且唯一的,它允许客户端在不同的 POP 会话中访问相同的消息。邮件由消息号检索并标记为删除。当客户端退出会话时,标记为删除的邮件将从 maildrop 中删除。-维基百科

然而,基本LIST命令似乎只是返回一个临时数字数组以允许您获取电子邮件。这些数字绝不是唯一的,因此似乎添加了另一个名为 UIDL 的扩展:CAPA(POP3 扩展机制)。

POP3声明,UIDL只要消息存在,a 就是唯一的。

消息的唯一 ID 是由服务器确定的任意字符串,由 0x21 到 0x7E 范围内的 1 到 70 个字符组成,它唯一地标识了邮件投递中的消息,并且在会话中持续存在。即使会话结束而没有进入 UPDATE 状态,也需要这种持久性。只要存在使用唯一 ID 的实体,服务器就不应在给定的邮件投递中重用唯一 ID。

请注意,标记为已删除的邮件未列出。

虽然服务器实现通常最好将任意分配的唯一 ID 存储在邮件投递中,但本规范旨在允许将唯一 ID 计算为消息的哈希值。客户端应该能够处理邮件投递中消息的两个相同副本具有相同唯一 ID 的情况。

这让我认为一年后我可能会下载另一条消息(在第一条消息被删除之后),它具有相同的 UIDL 并且可能在我的系统中发生冲突。

我是否应该对整个消息正文进行哈希处理并将其用作 ID?

而不是获取整个电子邮件来散列它,也许我应该只使用TOP [id] 1散列不应该与现有电子邮件匹配的标题(和第一行),因为接收服务器总是会正确添加某种类型的信息?所以攻击者永远不会引起冲突,因为收到的东西应该已经被修改了,对吧?

MDaemon 程序似乎解决了部分标头散列的问题:

MDaemon 使用消息名称、日期戳、大小和有关消息的一些其他详细信息来构造 UIDL 结果。因此,如果邮件在服务器上被修改,即使您不重命名它,它也会对邮件客户端显示为“新”。

为 POP3 电子邮件创建 ID 的正确方法是什么?

注意:电子邮件通常包含Message-ID标题 - 但我不能依赖它,因为它可能被用作攻击媒介来混淆我的系统。一些电子邮件客户端也忽略了它。

4

3 回答 3

3

就个人而言,我只会散列一小部分电子邮件标头:例如Date, From, Subject, 和Message-ID如果可用。

我经常订阅邮件列表,当有人回复您时,您往往会收到同一消息的多个副本——一个直接来自他们,另一个通过邮件服务器。在这种情况下,许多标题是不同的,但我真的不想收到两份消息。

而且我同时收到来自同一个人的两封不同的电子邮件,主题相同,邮件编号相同的可能性似乎极小。

当然,也不是不可能。他们可能不会生成消息 ID,他们可能有一个空白的主题行,他们可能有一个坏了的时钟,他们可能同时拥有所有这些东西。但是话又说回来,他们的电子邮件通过的路由器可能会被来自太空的巨大流星摧毁。

坦率地说,最有可能的情况是电子邮件最终会被垃圾邮件检测到,而我无论如何也看不到它。电子邮件只是一种不那么可靠的交流方式。你需要一些工作得相当好的东西,但如果它不能处理百万分之一的边缘情况,你可能仍然可以。

于 2013-05-09T20:49:15.750 回答
1

请原谅我质疑你的问题,但是——真正的问题是:你为什么在乎?在我看来,您正在努力想出一个自然的电子邮件主键。你不应该需要——反正也没有。您要解决的真正问题是什么?

您对 UIDL 的理解是正确的。消息在特定邮箱中时必须保持相同的 UIDL,相同的消息可以具有相同的 UIDL(但不需要),并且 UIDL不应在邮箱的上下文中重复,但并非严格要求。最后一个要求特别强调了 UIDL 的范围和目的。一旦客户端从邮箱中删除了一条消息,它必须(并且可以)忘记它的 UIDL,因为如果它再次出现,该值将永远不会传达与前一条消息的任何关系。

于 2013-05-07T20:57:50.013 回答
0

我将散列您提到的 UIDL,以及您应该确保数字唯一性的当前时间戳。如果只要消息离开,UIDL 就是唯一的,那么使用时间戳将确保您引用的场景(具有相同 UIDL 的另一条消息)不会发生!

于 2013-05-10T13:09:51.203 回答