【问题标题】:Storing sensitive data in database, recommendation在数据库中存储敏感数据,推荐
【发布时间】:2017-11-26 21:34:38
【问题描述】:

我正在寻找将敏感数据存储在数据库中的最佳解决方案。 我知道这是一个普遍的问题,我已经完成了我的功课(至少我是这么认为的),但是我想在这里问一下,然后再做决定。

假设:

  • 加密数据需要解密。我们正在讨论 SMTP 凭据,例如用户名、密码、主机、端口 itp。

我在考虑两个概念:

  1. 借助 passlib.totp 库加密数据。为了使这些数据更安全,我会将密钥保存在单独的文件中。然后据我所知,我可以使用这个库使用我的密钥将数据解密为纯文本。

  2. 另一个概念是在查询请求期间借助 postgres 加密和解密数据:

    insert into demo(pw) values ( encrypt( 'data', 'key', 'aes') );
    

    还有:

    decrypt(pw, 'key', 'aes'), 'utf-8')
    

    这里的密钥也将存储在单独的文件中。

所以我的问题是:

  1. 在代码中还是在数据库中加密/解密数据的更好方法是什么?
  2. 有没有比 passlib.totp 更好(更强大)的库可供使用 -> 我没有使用该库的经验(我知道加密/解密不是存储密码的最安全方式 -> 密码应该是hased,但我需要它以纯文本形式使用用户 smtp 门)。

【问题讨论】:

  • 问自己一个问题:这将保护您免受什么样的威胁?因为显然,如果有人获得了您系统的访问权限,则密钥以及数据库内容都可能受到损害......
  • 是的,我知道这一点。但是,如果有人只能通过 sql 注入访问数据库内容(由于对输入字段的保护较弱),那么我认为这将为这些数据提供一些保护。我完全意识到这不是 100% 可靠的子弹教授概念。再说一次,例如,您有员工要授予他们读取数据库(或其中一部分)的访问权限,但您不想让他们以纯文本形式查看密码,他们无权访问文件结构.所以我认为在某些情况下这很有用。
  • 始终加密和解密客户端。人们可以读取您的网络流量,否则为纯文本。这并不完全与编程相关,所以请移到这里security.stackexchange.com
  • @cricket_007 - 假设作者想使用这些凭据来执行一些后台任务,您的建议不能在这里应用。
  • 嗯,除其他外,这确实有助于备份在系统外部时不会不安全。此外,一些国家/地区制定了有关数据泄露/丢失的义务的立法,并区分加密和未加密。对于security.stackexchange.com,也许这是一个更好的问题

标签: python database postgresql security passwords


【解决方案1】:

2) 另一个概念是在查询请求期间借助 postgres 加密和解密数据:插入 demo(pw) 值(加密('data','key','aes'));和 decrypt(pw, 'key', 'aes'), 'utf-8') 这里的密钥也将存储在单独的文件中。

我不建议这样做,因为在pg_stat_activity、日志等中暴露密钥太容易了。PostgreSQL 没有日志屏蔽功能可以防止那个。

我强烈建议您使用应用端加密。如果安全至关重要,请使用加密卸载设备,因此大多数攻击者无法提取密钥。或者要求管理员在应用程序启动时输入密码来解锁密钥,因此密钥永远不会未加密地存储在磁盘上 - 然后攻击者必须从内存中窃取它。但是,即使是某个不明显的未加密密钥文件也比 IMO 数据库内加密更好,因为它至少将密钥与数据分开。

【讨论】:

  • 谢谢。至少我现在知道选项 2 是完全错误的。
【解决方案2】:

最终,您的应用程序需要能够使用某种密钥恢复明文密码。如果您的系统受到威胁,您必须​​假设恶意用户会简单地找到您的密钥(无论是在数据库中还是在磁盘上)并执行与您的应用程序完全相同的解密操作。

当您的系统需要以可恢复的形式存储密码时,即与外部系统进行身份验证时,您最多只能混淆该信息。这就是人们提到“通过默默无闻的安全”时的意思,这是个坏主意。

当您表面上提供安全性,而没有实际上保护某些东西,那么这会使事情变得更加危险。您或其他管理系统的人可能会忽略其他重要的安全措施,因为他们认为敏感信息已经有了一层保护。与假设保护信息的唯一方法是保护保存它的系统相比,它可能会造成敏感信息可能更多泄露的社会情况。它还可以使人们相信,如果数据从数据库中被盗,“也许没关系,因为他们无法解密它”。这就是您最终负责将凭据泄露给全世界的原因,因为您必须假设如果您的应用程序可以获取纯文本数据,那么已经破坏您的应用程序的攻击者也可以。

在多个系统上加密一个多部分密钥可能有一个非常非常小的优势(即文件系统中的一部分,数据库中的一部分),因此获得对一个系统的访问权限的人不会不一定能接触到对方。可以合理地说,这实际上可能会延迟攻击或阻止懒惰的攻击者。但是,一般来说,您的应用程序所在的地方无论如何都可以访问这两个东西,因此如果您的应用程序受到损害,那么您必须假设数据受到损害。 (编辑:您在另一条评论中提到您的用户 a)不应该知道存储在数据库中的密码,但 b)可以直接访问数据库。相信我,如果您这样做,其中一个用户获得所有这些密码的可能性不为零。沿着这条路走下去,你就相信了一个有缺陷的保护层。)

tl;dr 存储敏感数据时的可逆加密很少具有实用、真实的安全价值。如果您尝试勾选合规性复选框,并且您无权否决需要您勾选该框的链条上的某个人,那么请务必实施一些“加密”数据的方法。但是,如果您实际上是在尝试保护您的系统,请寻找其他地方:这里是龙。

【讨论】:

  • 感谢您花时间编写所有这些内容。很难不同意你的观点。但它根本没有回答我的主要问题。问题是:如果我必须加密解密(原因并不重要),最好在代码中执行此操作或使用数据库,如果在代码中,什么是最合适的工具。这是那个问题的主要目的。我没有问“我是否应该这样做”->根本不在该问题的范围内。但无论如何,谢谢,有趣的讲座。
  • @daveruinseverything 保护您的密码的最佳方法是不存储它们 :-) 尽管上述答案是在假设攻击者获得对系统的完全控制权的情况下做出的。不是专家,感觉在大多数情况下,通过在服务器上执行查询来获得完全访问权限会更加困难。在这种情况下,不以模糊的形式存储这些访问凭据会不会有帮助?
【解决方案3】:

您可以查看Vault project,这是一个秘密管理工具:

一般秘密存储

至少,保险柜可用于存储任何秘密。 例如,Vault 将是存储敏感信息的绝佳方式 环境变量、数据库凭据、API 密钥等。

将此与当前存储这些可能的方式进行比较 文件中的明文、配置管理、数据库等。 使用 Vault Read 或 API 查询这些会更安全。这 保护这些秘密的明文版本以及记录 Vault 审核日志中的访问权限。

员工凭证存储

虽然这与“通用秘密存储”重叠,但 Vault 是一个不错的选择 用于存储员工共享以访问网络的凭据的机制 服务。审计日志机制让您知道哪些秘密 员工访问,当员工离开时,更容易滚动 键并了解哪些键已滚动和未滚动。

Vault 服务器以加密形式存储数据。可以通过命令行或 REST API 检索数据。服务器必须在unsealed state 中才能返回解密数据——解封需要特定数量的主密钥分片。服务器重启后,需要再次开封。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 2012-03-28
    • 2017-09-05
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    相关资源
    最近更新 更多