python中的安全凭证存储

2024-09-22 22:35:36 发布

您现在位置:Python中文网/ 问答频道 /正文

攻击

在凭据存储环境中,一种可能的威胁模型是攻击者,该攻击者能够:

  • 检查任何(用户)进程内存
  • 读取本地(用户)文件

AFAIK,关于这类攻击的共识是不可能防止(因为凭据必须存储在内存中,程序才能实际使用它们),但有两种技术可以减轻这种攻击:

  • 最小化敏感数据在内存中的存储时间
  • 一旦不再需要数据就覆盖内存
  • 损坏内存中的数据,继续移动它,并通过模糊措施实现其他安全性

特别是Python

第一种技术很容易实现,可能是through a keyring(希望是内核空间存储)

据我所知,如果不编写一个C模块,第二个模块是完全不可能实现的(但我希望在这里被证明是错误的,或者有一个现有模块的列表)

第三个很棘手。

特别是,python是一种具有非常强大的内省和反射功能的语言,很难阻止任何可以在解释器进程中执行python代码的人访问凭据。

似乎有一种共识是there's no way to enforce private attributesattempts at it will at best annoy other programmers who are using your code

问题

考虑到所有这些,如何使用python安全地存储身份验证凭据?最佳实践是什么?语言“一切都是公共的”哲学能做些什么吗?我知道"we're all consenting adults here",但我们是否应该被迫在与攻击者共享密码和使用其他语言之间做出选择?


Tags: 模块文件数据内存用户模型程序语言
2条回答

我不是这个领域的专家,我真的只是想解决和你一样的问题,但是看起来像Hashicorp's Vault这样的东西也许能很好地帮助你。

特别是与存储第三方服务凭据的问题有关。e、 g.:

In the modern world of API-driven everything, many systems also support programmatic creation of access credentials. Vault takes advantage of this support through a feature called dynamic secrets: secrets that are generated on-demand, and also support automatic revocation.

For Vault 0.1, Vault supports dynamically generating AWS, SQL, and Consul credentials.

更多链接:

存储身份验证凭据有两个非常不同的原因:

  1. 要验证您的用户:例如,您只允许用户在验证您的程序之后访问服务
  2. 要使用另一个程序或服务验证程序:例如,用户启动程序,然后使用IMAP通过Internet访问用户的电子邮件。

在第一种情况下,不应存储密码(或密码的加密版本)。相反,您应该使用高质量的salt来散列密码,并确保使用的散列算法在计算上非常昂贵(以防止字典攻击),例如PBKDF2或bcrypt。有关更多详细信息,请参见Salted Password Hashing - Doing it Right。如果您采用这种方法,即使黑客检索盐渍的、慢散列的令牌,他们也不能用它做很多事情。

在第二种情况下,为了使秘密发现更加困难(正如您在问题中概述的那样),需要做很多事情,例如:

  • 在需要前对机密进行加密,按需解密,然后在需要后立即重新加密
  • 使用地址空间随机化,因此每次应用程序运行时,密钥都存储在不同的地址
  • 使用OS密钥库
  • 使用“硬”语言,如C/C++,而不是基于VM的内省语言,如java或Python

这样的方法当然比什么都没有要好,但熟练的黑客迟早会把它破解的。

代币

从理论上讲,认证是证明被质疑者是他们所说的人的行为。传统上,这是通过共享的秘密(密码)来实现的,但也有其他方法来证明自己,包括:

  • Out-of-band身份验证。例如,在我居住的地方,当我试图登录我的网银时,我在手机上收到一条one-time password(OTP)短信。在这种方法中,我通过拥有一个特定的电话号码来证明我是
  • Security token:要登录服务,我必须按令牌上的一个按钮以获取一个OTP,然后将其用作密码。
  • 其他设备:

    • SmartCard,特别是美国国防部使用的,在那里它被称为CAC。Python有一个名为pyscard的模块来接口这个
    • NFC设备

以及更完整的列表here

所有这些方法的共同点是,最终用户控制这些设备,而这些秘密实际上永远不会离开令牌/卡/电话,当然也永远不会存储在您的程序中。这使他们更加安全。

会话窃取

然而(总是有一个然而):

假设您成功地保护了登录,这样黑客就无法访问安全令牌。现在,您的应用程序正愉快地与安全服务交互。不幸的是,如果黑客可以在您的计算机上运行任意可执行文件,那么黑客可以劫持您的会话,例如,在您有效使用服务时插入其他命令。换句话说,虽然你已经保护了密码,但它完全不相关,因为黑客仍然可以访问“安全的”资源。

这是一个非常真实的威胁,正如多个跨站点脚本攻击所显示的那样(一个例子是U.S. Bank and Bank of America Websites Vulnerable,但还有无数的例子)。

安全代理

如上所述,在第三方服务或系统上保留帐户凭据是一个基本问题,以便应用程序可以登录到该帐户,特别是在唯一的登录方法是用户名和密码的情况下。

一种通过将通信委托给安全代理来部分缓解这种情况的方法,并在应用程序和代理之间开发一种安全登录方法。在这种方法中

  • 应用程序使用PKI方案或双因素身份验证登录到安全代理
  • <升i> 用户将安全凭据添加到安全代理的第三方系统。凭证从未存储在应用程序中
  • 稍后,当应用程序需要访问第三方系统时,它会向代理发送请求。代理使用安全凭据登录并发出请求,将结果返回给应用程序。

这种方法的缺点是:

  • 用户可能不希望信任具有凭据存储的安全代理
  • 当数据通过安全代理流向第三方应用程序时,用户可能不信任该安全代理
  • 应用程序所有者有额外的基础设施和托管成本来运行代理

一些答案

所以,具体回答如下:

How does one securely store authentication credentials using python?

  • 如果为应用程序存储用于验证用户身份的密码,请使用PBKDF2算法,例如https://www.dlitz.net/software/python-pbkdf2/
  • 如果存储密码/安全令牌以访问其他服务,则没有绝对安全的方法。
  • 但是,考虑使用pyscard将身份验证策略切换到智能卡等。您可以使用智能卡对应用程序的用户进行身份验证,也可以使用X.509证书对应用程序的其他服务进行安全身份验证。

Can something be done about the language "everything is public" philosophy? I know "we're all consenting adults here", but should we be forced to choose between sharing our passwords with an attacker and using another language?

IMHO在Python中编写一个特定的模块没有什么不对的,这样做最该死的是隐藏秘密信息,使它成为其他人重用的正确bug(烦扰其他程序员是它的目的)。你甚至可以用C编写大部分代码并链接到它。但是,出于明显的原因,不要为其他模块执行此操作。

不过,归根结底,如果黑客控制了电脑,电脑上根本就没有隐私。理论上最糟糕的情况是,你的程序运行在一个虚拟机上,黑客可以完全访问计算机上的所有内存,包括BIOS和图形卡,并且可以通过身份验证来逐步发现你的应用程序的秘密。

由于没有绝对的隐私,剩下的只是模糊化,而保护的级别只是模糊化的难度与熟练的黑客需要信息的程度之比。我们都知道如何that ends,即使是custom hardwarebillion-dollar products

Using Python keyring

虽然这将非常安全地管理与其他应用程序相关的密钥,但所有Python应用程序都可以共享对令牌的访问。对于你担心的那种攻击,这一点都不安全。

相关问题 更多 >