Python 在数据库中存储敏感数据,建议

Python 在数据库中存储敏感数据,建议,python,database,postgresql,security,passwords,Python,Database,Postgresql,Security,Passwords,我正在寻找在数据库中存储敏感数据的最佳解决方案。 我知道这是一个常见的问题,我已经做了家庭作业(至少我是这么想的),但我想在做决定之前先问一下 假设: 加密的数据需要解密。我们正在讨论SMTP凭据,如用户名、密码、主机、端口itp 我在想两个概念: 使用passlib.totp库对数据进行加密。为了使这些数据更安全,我将把密钥保存在单独的文件中。然后,从我所看到的,我可以使用这个库使用我的密钥将数据解密为纯文本 另一个概念是在postgres的帮助下在查询请求期间加密和解密数据: inser

我正在寻找在数据库中存储敏感数据的最佳解决方案。 我知道这是一个常见的问题,我已经做了家庭作业(至少我是这么想的),但我想在做决定之前先问一下

假设:

  • 加密的数据需要解密。我们正在讨论SMTP凭据,如用户名、密码、主机、端口itp
我在想两个概念:

  • 使用passlib.totp库对数据进行加密。为了使这些数据更安全,我将把密钥保存在单独的文件中。然后,从我所看到的,我可以使用这个库使用我的密钥将数据解密为纯文本

  • 另一个概念是在postgres的帮助下在查询请求期间加密和解密数据:

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

    在此,密钥也将存储在单独的文件中

  • 因此,我的问题是:

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

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

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

    如果你给人一种安全感的外表,而不是真正的安全感,那么这会使事情变得更加危险。您或管理系统的其他人员可能会忽略其他重要的安全措施,因为他们认为敏感信息已经有了一层保护。它可能会造成一种社会状况,在这种情况下,敏感信息可能更容易泄露,而不是假设保护信息的唯一方法是保护持有信息的系统。这也会让人们相信,如果数据库中的数据被盗,“也许没关系,因为他们无法解密”。这就是你最终要为向全世界泄露凭据负责的原因,因为你必须假定如果你的应用程序可以获取明文数据,那么危害你的应用程序的攻击者也可以

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

    tl;dr可逆加密在存储敏感数据时很少有实际的、真正的安全价值。如果您试图勾选一个合规性复选框,而您没有权力否决链上需要您勾选该复选框的人,那么请务必实施某种“加密”数据的方法。但如果你真的想保护你的系统,看看别处:这里有龙

    您可以查看管理机密的工具:

    一般秘密存储

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

    将其与当前存储这些信息的方法进行比较 明文文件、配置管理、数据库等 使用vault read或API查询这些将更加安全。这 保护这些机密以及记录的纯文本版本 在Vault审核日志中访问

    员工凭证存储

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

    Vault服务器以加密形式存储数据。可以通过命令行或RESTAPI检索数据。服务器必须处于返回解密数据的状态-解封需要特定数量的主密钥碎片。服务器重新启动后,您需要再次将其解封

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

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

    我强烈建议您使用应用程序端加密。如果安全性至关重要,请使用加密卸载设备,这样大多数攻击者就无法提取密钥。或要求钥匙由
    decrypt(pw, 'key', 'aes'), 'utf-8')