Password Encryption , storing password in session
我需要存储密码并再次使用它。我觉得这根本不安全。
脚本:
我想创建一个Webmail程序,在那里用户用用户名和密码登录,然后检查他们的电子邮件。此工具不打算在数据库上存储密码。但是在PHP中,我们需要在用户导航到的每个页面中连接到邮件服务器。所以连接到邮件服务器需要用户名和密码。如何才能以最安全的方式做到这一点?
- 为了澄清,您正在创建一组将由浏览器访问的PHP网页,对吗?这些页面将提供对其他邮件服务器的访问,它需要用户名和密码来访问这些服务器?是否需要存储一个用户将输入的用户名/密码,并将其与会话保持关联?更多的细节会使你更可能得到一个有用的答案。
- 是的,大卫。有很多页。每个页面都需要以前的用户名和密码才能连接。PHP无法在页之间传递连接处理程序。所以我需要在很多页面上保留连接的用户名和密码。由于这个工具被很多用户使用,我们不能存储他们的密码,这是对他们隐私的侵犯。希望我说得对……
- 客户端用户界面是否为javascript?如果不是,可能应该是。它可以为你存储密码。
- 我想问题是,在用户向您提供登录信息并连接到邮件服务器之后,您能缓存邮件会话吗?
- Daivd,我的用户界面,仅限PHP和HTML。没有javascript。当用户第一次登录时,我们连接到邮件服务器。在导航到其他页面时,请使用相同的详细信息进行连接。那么,是否可以在具有更高安全性的会话中存储密码?或者有其他的选择吗?
- Jared,我确信我们不能使用php缓存到pop/imap服务器的连接。接下来是如何在其他页面上建立连接,而不询问用户导航到的每个页面的登录详细信息。
- 所以我好像不明白这个道理。您基本上只想将某人提供的登录您站点的用户名和密码转发到邮件服务器?那么,将它保存在会话中有什么障碍呢?当然,有权访问您机器的人可以直接读取会话存储区,但您无法保护此类数据(加密不会做任何事情)。
- @Kiran:你打算在用户做任何事情的时候用一个全新的网页替换整个用户界面吗?您认识到这将使一个应用程序,按现代标准,无法使用。
- 你总是可以看看松鼠邮件是怎么做到的。
由于不打算存储密码,但也不希望多次重新输入密码,因此我看到的唯一解决方案是:
- 用足够长的随机密钥加密密码(如aes)
- 在会话中存储加密的密码和用户名
- 为了以防万一,对用户名和邮件服务器进行加密也可能是正确的。它不会造成伤害,并且假定攻击者在服务器上没有已知的用户名。
- 将加密密钥存储在cookie中
这不是完美的,但它应该能很好地工作,而且它可能是一个很好的折衷办法。
对于每个请求,用户的浏览器将发送cookie,php脚本可以使用cookie解密会话中存储的数据,并在imap/pop服务器上执行请求。
有人利用您的服务器并获得对会话存储的访问权,将能够窃取加密的密码,但是如果您的随机密钥有足够的长度和良好的随机质量,这是非常徒劳的。
关键是,你只能用一个你不知道的秘密来真正地保护一些东西。如果您有必要的信息来解密服务器上的某些信息(本例中是IMAP密码),例如会话存储区中的信息,那么使用服务器的每个人都可以这样做。不管你的加密有多强,它都没有任何区别。确保秘密保持秘密的唯一方法是用一些你不知道的东西,一些只有用户(在本例中是用户的浏览器)知道的东西对它们进行加密。
这导致了一个无法解决的问题,在某个时间点上,你显然必须知道,至少在一瞬间。这是Web服务器接收cookie和退出PHP脚本之间的时间。理论上,如果有一个具有根访问权限的人在这段时间内读取进程内存,他也会知道这个秘密。但是,唉,这是你无法阻止的。但是,只要信息从未存储在任何地方(甚至在会话中),它就应该是相当安全的。
当然,所有这些都假定至少站点上的登录页面(最好全部)是通过https://提供的,并且您使用tls/ssl与邮件服务器通信。否则,您将面临更为微不足道的攻击。
- 你好,这解释了我的问题和安全问题。非常感谢您分享这些宝贵的信息。
- 很好的答案,但是存储应该与您的建议相反。加密密钥应存储在会话中,加密的用户名和密码应存储在cookie中。如果有人访问会话存储,他们将拥有大量的密钥,但没有任何用户名和密码,他们可以尝试强行。
- @用户3332631:这通常是正确的,消除每一个可能的泄漏肯定不会有什么坏处。虽然实际上,如果您选择一个非平凡的密钥长度(如128位),那么强制执行是不切实际的。即使是像美国间谍机构这样大的人,也不可能为了热力学上的限制(不管CPU的功率如何)而强行使用一个128位的密钥。如果第三次世界大战的结果依赖于它,他们可能会做一个键,但是对于服务器上的任何键(更不用说其中的许多键)来说,这都是不切实际的。你还不够重要,不能强行128位。
- 为了弄清楚我所说的"不切实际"和"不够重要",通过128位计数(密钥设置和16轮AES是另一回事!)假设一个完美的中央处理器,将消耗相当于美国总铀产量数年的电能。这意味着你必须有一个非常重要的秘密才能发生(然后他们宁愿用扳手攻击你)。在随机的服务器上,阅读某人不重要的电子邮件并不是一件例行的事情。
- 好吧,暴力是不可能的。只需提到,执行此操作的其他系统将密钥存储在会话中,密码存储在cookie中。参考:squirrelmail.org/docs/devel code/squirrelmail/…不知道除了在会话存储中使用暴力之外,是否还有其他原因。也许归根结底,这就是你所能享受的。
- @达蒙:我还有一个问题。为什么我们要使用这个方案而不是基本的访问认证?理论上它不是做同样的事情吗,或者BA不方便,因为它可以随时超时?
- @用户3332631:基本访问认证是为了让您访问某个特定的页面,它对OP想要做的事情没有帮助(至少我无法想象它会有什么帮助)。问题是如何在不将用户名+密码存储在数据库中的情况下存储用户名+密码,并确保其安全。唯一保证安全的方法是如果你不知道密码,或者你不知道加密密钥。最安全的事情就是永远不要把它发送到服务器。但是,服务器最终必须暂时拥有密钥,因为它代表用户发出请求。
- @达蒙:"你只能用一个只有你不知道的秘密来真正地保护一些东西。"实际上,"你只能得到你知道的东西"(只有我的2美分)。但在一个真正的(如商业)应用中,你还需要一些其他的用户数据(如卡、ID、地址等),因此mysql的用户名/密码表仍然不够。如果你需要加密和解密这些数据,我想在现实世界中服务器安全仍然是最重要的,因为你必须把你的解密密钥放在上面。