在数据库中存储用户电子邮件地址的最佳和最安全的方式是什么?

27

出于安全考虑,是否值得在将用户电子邮件放入数据库之前对其进行加密?

我知道我们会对密码进行哈希和盐处理,但这是另一个故事,因为我们实际上不需要密码原文。但电子邮件则不同。

考虑到解密密钥仍然会在数据库附近某个地方,那么加密电子邮件是否有意义?我想,如果有人进入系统,他们也会找到密钥,即使不能立即找到,最终也可能找到。

有什么最佳实践吗?如果我运行自己的服务器而不是共享/虚拟主机,是否还有其他选项可用?

编辑:我打算使用SQL Server。并且,这不是具有安全要求的企业软件,只是我心中的一些娱乐网站。

10个回答

31

如果您将来需要使用电子邮件地址,则必须以明文形式存储它们。

当然,您可以对其进行加密,但在这种情况下,这实际上是通过“安全性非显而易见性”来保护安全性。基本上,如果您的应用程序外围边界很安全,您的数据可以是明文的。在此加密会增加您处理数据的复杂度,但并不能真正阻止攻击者获取您的原始数据。

正如您所说,如果他穿过了您的外围防线,他很可能轻易地获得解密电子邮件数据的解密密钥。加密可能稍微减慢坚决攻击者的速度,但不会为您的数据添加任何真正的安全性。

最好的方案是对电子邮件地址进行哈希(记得使用盐!)并将其存储。这样,您就可以检查电子邮件地址是否与输入值相同(例如),并验证电子邮件地址输入是否与您存储的相同。当然,这种方法的主要缺点是,如果您想要定期向用户发送电子邮件之类的事情,您就无法知道电子邮件地址是什么。

我猜您正在存储电子邮件地址,因为它是有用的数据,而且您会想要做一些事情(例如发送电子邮件:) ),在这种情况下,加密只会增加处理该数据时的开销,同时几乎没有任何回报。

在这种情况下,我建议将重点放在保护数据库本身的访问上(即您的“外围”防御),确保它们尽可能强而有力,同时将数据保留为明文存储在数据库中。


3
好的分析,非常有深度。+1 - Cardinal System

14

希望这个答案也能回答您的问题。

在数据库中加密电子邮件地址是否值得?

简而言之,不值得对用户的电子邮件地址进行加密。您的想法是正确的,数据库被破坏后,可能会有人获得破解加密所需的密钥。


我看过这个,但它似乎相当狭窄。我想听听关于电子邮件安全方面的任何想法。 - User
3
有时服务器被攻击者入侵后,仅允许其查看数据库内容本身,而保留密钥,从而保护了数据。但是,指望这种情况发生是荒谬的。 - tylerl
我必须同意其他回答这个问题的人。大多数电子邮件地址都被垃圾邮件淹没了。那些没有被垃圾邮件淹没的通常已经设置了垃圾邮件拦截,如果用户的密码是“password”,并且有人找到了他们的电子邮件地址,那么任何加密都无法保护用户。不过,我会遵循@MaxVT的建议,对电子邮件地址进行清理/验证。如果您仍然担心安全问题,像@zoomzoom83建议的使用数据库范围的加密也是一个好主意。 - Brett Bender
当公开电子邮件地址时,我认为垃圾邮件并不是真正的问题。通常,电子邮件地址是个人详细信息,用于识别用户。当针对SQL注入进行处理时,数据库范围内的加密才会有用,当然,这应该是必须做到的。 - Arjan

10
总体而言,我同意其他人的观点,认为这不值得花费精力。然而,我不同意任何可以访问您数据库的人可能也能够获取您的密钥。这在SQL注入方面肯定不是真的,并且在某些已经丢失或被遗忘的备份副本中也可能不是真的。我认为电子邮件地址是个人信息,所以我关心的不是垃圾邮件,而是在这些地址被公开时的个人后果。
当然,如果您担心SQL注入,那么您应该确保禁止此类注入。备份副本应该自己加密。
对于一些在线社区,成员们可能绝对不希望别人知道他们是成员(例如与心理保健、金融援助、医疗和性建议、成人娱乐、政治等相关)。在这些情况下,尽可能少地存储个人信息并加密所需的信息(请注意,数据库级别的加密不能防止使用SQL注入显示详细信息),可能不是一个坏主意。再次强调:要将电子邮件地址视为个人敏感信息。
对于您的娱乐网站而言,这可能不是问题,您应该专注于通过SQL注入禁止“SELECT * FROM”,并确保访问者无法通过更改URL访问他人的个人资料或订单信息。

我将数据库转储上传到GitHub上,因此需要一些方式来混淆电子邮件。 - posfan12

9
在计算机安全领域,经常引用的真理是:唯一真正安全的计算机是被深埋在混凝土中、断电并断开网络电缆的计算机。
有了这个想法,最安全的存储电子邮件地址的方法是什么?干脆不存储!
简而言之,你需要他们的电子邮件地址,还是需要一种发送电子邮件的方式?要么相信比你做得更好的人,要么干脆不使用电子邮件地址。
为什么要记录客户的电子邮件地址?我遇到的唯一原因是:
- 账户确认和身份验证 - 交易和营销电子邮件
身份确认的核心是两步验证:他们知道的东西和他们拥有的东西。他们知道的是密码,很容易证明,因为只有他们自己知道。他们拥有的东西则难以证明,传统上我们使用电子邮件地址,因为它很容易验证。然而现在有其他可以使用的东西。
  • 手机
  • 在可信任的网站上注册账号(Facebook,Google,Twitter)

手机验证很简单。使用类似twilio.com的服务向他们发送短信,并要求他们回复确认码。现在我们知道该手机属于想要注册的客户。使用OpenID,您可以验证其他受信任站点上的现有帐户,确认过程由它们处理。

对于客户进行身份验证,他们只需要提供其手机号码和密码或OpenID身份验证令牌即可。两者都不需要电子邮件地址(虽然OpenID提供者可能需要,但这不是您的责任)。

如果这些选项不可用,则仍然可以确认电子邮件地址,然后将其用于身份验证。确认仅需要存储唯一令牌并向电子邮件地址发送链接。存储电子邮件地址的加盐哈希值,并像处理密码一样使用它来匹配帐户。

交易和营销电子邮件

我们想要存储电子邮件地址的真正原因是为了向他们发送我们认为他们需要的东西的优惠,以便他们可以在不阅读它的情况下将其删除。但说真的,电子邮件是最好的媒介吗?如果我们拥有一个OpenID账户,为什么不用它来进行通知呢?发送Facebook消息或在他们的墙上写字,在Twitter上@提到他们,发送短信到他们的手机,构建应用程序并向他们推送通知。有许多比电子邮件更有效的渠道。
如果您想使用电子邮件,请使用像MandrillMailChimp这样的电子邮件平台。当他们注册时,在MailChimp的邮件列表中创建一个订阅者。将订阅者ID与该帐户一起存储。对于交易电子邮件(重置密码,帐户更新),获取订阅者并将存储的电子邮件传递给Mandrill发送电子邮件。对于大规模营销,只需发送到MailChimp的邮件列表即可。
数据库中仅存储订阅者ID。使用电子邮件平台还可获得退订、开启和点击率、电子商务跟踪等所有好处。与您相比,电子邮件平台能更好地发送电子邮件。它们还可以更好地保护数据隐私。让它们负责数据库安全的繁重工作,这样您就可以专注于获取更多客户。

2
我认为,如果有人能进入你的数据库,那么你就已经完蛋了 :)
仅仅加密电子邮件地址并没有多大意义。除此之外,你的数据库中可能会包含很多其他信息,你不希望这些信息被获取,而解密密钥也将同时处于开放状态。
我建议在更高的层次上找到安全和数据完整性的保障措施,以避免他人进入你的数据库。
那么,为什么电子邮件地址如此重要呢?大多数人都会受到垃圾邮件的困扰,或者他们的电子邮件地址在互联网上某个地方都可以找到。

1

这取决于您访问地址的频率。如果您偶尔读取它们,那么这可能是有意义的,但这将是我花时间解决的最后一个安全问题之一。


1

我不加密用户的电子邮件。重点是保护数据库;如果您实际上想要使用存储的电子邮件,密钥仍然是可访问的。

但请检查地址的有效性和可能的SQL注入。


1
如果应用服务器和数据库位于不同的服务器上,将所有或部分数据库加密通常会增加安全性。
即使它们在同一台机器上,黑客也可能无法找出您的密码存储位置(尽管我不会依赖这一点)。
通常情况下,我不会在应用程序级别对电子邮件进行加密,而是依靠大多数企业数据库提供的数据库范围内的加密。
当然,如果您使用的是MySQL之类的东西,则只能在应用程序级别执行。
我通常告诉我的客户,加密数据库并不值得麻烦,但是如果您有更严格的隐私要求,则这样做可能是有意义的。

1

加密数据库内容始终是一个棘手的考虑。显然,除非可以解密内容,否则内容是无用的,如果必须在没有人为干预的情况下进行解密,则需要在某个地方存储密文和密钥。如果这个“某个地方”在同一台机器上,那么人们可能会想知道你为什么要这样做。

好吧,有几个原因可能会促使你这样做。其中一个原因是因为由于某些公司政策的要求而必须这样做。另一个原因是,也许你的数据库所在的环境比访问它的机器更具敌意。

总的来说,加密数据库内容不会赢得任何奖项,但如果你能够证明其必要性,那么你显然至少有一些动力这样做。


0

如果您将其与盐一起哈希处理,可能对用户有所帮助。以前我曾经使用过这样的代码,我使用盐和哈希,然后可以解密它。流程是一旦用户注册,就进行哈希和盐(加密过程)。然后,如果需要获取加密数据,就会进行解密。


1
我认为你混淆了“哈希”和“加密”。 - SierraOscar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接