2

我在 Django 上运行一个网络服务。用户注册到我的系统并为我提供第 3 方网络服务的登录详细信息(用户名和密码)。

我的目的是以最好和最安全的方式存储这些详细信息。不幸的是,我的服务需要这些数据来查询第 3 方服务的一些离线脚本,因此我无法存储使用用户密码加密的登录名/密码(并将其用于解密它们的密钥。

我阅读了很多关于 stackoverflow 的文章,但其中大多数(例如:当 API 调用需要以纯文本形式发送密码时,将密码存储在数据库中的最佳方法是什么?)不需要“离线”访问这些数据。

我唯一的想法是将这些详细信息存储在一个非常安全的服务器上,该服务器只接受来自我的 django 服务器的请求,并通过 tls 进行通信。

你还有其他建议吗?

先感谢您!

4

2 回答 2

1

首先,其他文章是正确的:永远不要以纯文本形式存储密码。如果您得出需要以纯文本形式存储它们的结论,则需要重新考虑您的策略(Oauth?)。使用带盐的散列密码的全部原因是,即使出现问题,密码也是安全的(因为没有密码,只有散列......)。我实际上想知道您到底出于什么原因需要这些第三方用户名和密码?

如果您确实必须存储这些,请使用加密文件或数据库字段并进行设置,以便每当您的脚本运行时,您都需要手动输入解密密码。我在这里假设您不是每 5 分钟运行一次此脚本,而是每周运行一次。除此之外,请绝对确保执行此操作的服务器没有做任何其他事情并且没有其他本地用户,否则可能会分析内存并找到解密的密码。

总而言之,我仍然会说你正在尝试的事情非常非常危险,你应该非常小心地进行......

于 2013-04-30T15:01:51.523 回答
0

这是一个旧的,但要走的路是在存储密码之前对其进行加密。使用安全存储的密钥(即不在数据库中(或至少不在同一个数据库中)并且不在 Github 中)并将其加载到部署项目的环境中。这样,任何直接访问数据库的人都无法读取密码。

更多信息的可能来源

Cryptography 库是一个很好用的库,在上面的文章中有引用。

对于这个问题中描述的情况,我会在环境中放置一个加密密钥并将其加载到settings.py部署中,它看起来像这样:

生成密钥

from cryptography.fernet import Fernet

key = Fernet.generate_key()

如果库已安装到您的 Python 环境中,您可以在 Python 控制台中运行上述内容。

根据您部署应用程序的方式,您需要提供对其密钥的访问权限。以下是将其引入您的环境的一种方法:

export ENCRYPTION_KEY="<key>"

一旦你在你的环境中的设置中添加了这一行

ENCRYPTION_KEY=os.get("ENCRYPTION_KEY")

如何使用密钥?根据您的设置,您可以在模型上编写其他属性方法来获取和设置字段的值,例如

 class mymodel(models.Model):
    
  ....
  @property
  def password(self):
      f = Fernet(settings.ENCRYPTION_KEY)
      password = f.decrypt(self.<myfield>)
      return password

  @password.setter
  def password(self, password):
      f = Fernet(settings.ENCRYPTION_KEY)
      token = f.encrypt(<password>)
      self.<myfield> = token
      self.save()

其他选项可能是子类化另一个 django 模型字段并在那里添加功能。如果你只在一个地方这样做,那么上面应该没问题。

如何存储加密密钥取决于您,环境只是一种选择。这里的关键是将它保存在安全的地方,重要的是不要丢失它......或者祝你好运;)

于 2021-09-12T15:26:38.073 回答