我只允许某些用户访问,考虑使用简单的用户名/密码机制,因为设置客户端证书似乎对这个小项目来说有点过分。
当然,我无法从客户端向服务器上的服务器发送明确的密码普通HTTP,否则安装了wirehark / tcpdump的任何人都可以读取它。因此,我正在考虑以下机制:
HTTP服务器可以设置为HTTPS服务器
该服务器还具有用户名/密码数据库(密码可能会保存使用bcrypt)
客户端打开HTTPS连接,对服务器进行身份验证(因此需要服务器证书),并且在交换主密钥后,应对连接进行加密。
客户端发送用户名/密码明确显示在服务器上
服务器对密码运行bcrypt并将其与数据库中存储的密码进行比较
这种配置是否有问题?密码是通过加密连接发送的,因此应该是安全的。
#1 楼
是的,这是标准做法。进行其他任何操作都会带来最小的附加优势(如果有的话)(在某些情况下可能会损害安全性)。只要您验证与正确服务器的有效SSL连接,该密码就在网络上受到保护,并且只能由服务器读取。由于服务器无法信任客户端,因此在发送密码之前先伪装密码不会获得任何好处。无论如何,丢失信息的唯一方法是,如果SSL连接遭到破坏,并且如果SSL连接受到某种程度的破坏,则“伪装”令牌仍然是访问帐户所需的全部东西,因此进一步保护密码并没有好处。 (可以说,如果他们在多个帐户上使用了相同的密码,确实可以提供轻微的保护,但是如果这样做,他们一开始并不特别注重安全性。)
正如MyFreeWeb指出的那样,也有一些复杂的系统可以使用质询响应来确保密码由客户端保存,但是这些系统确实很复杂,根本没有被广泛使用。它们还不能提供很多额外的优势,因为它们只能保护密码不被主动入侵的服务器泄露。
评论
@AJHenderson +1,让客户端发送哈希肯定是不好的,因为身份验证协议的重点是确保访问者知道正确的密码,而不是正确的密码哈希。如果恶意方可以获取哈希值(被盗的密码数据库,中间的人,等等),并且系统依靠访客发送哈希值而不是密码,那么任何真正的安全概念都将成为现实。
– Craig
2014年8月4日在20:04
有时在客户端进行哈希处理然后在服务器上进行哈希处理是有好处的。这可以帮助确保在客户端,服务器和网络上的任何明文日志中都混淆了密码。
– Andy Boura
2014年8月5日在7:41
@Craig让客户端计算昂贵的盐化哈希值是完全可以的,只要您在存储之前在服务器上应用便宜的无盐哈希值即可(或其他某种单向函数,例如模块化幂运算)。
– CodesInChaos
2014年8月5日在12:29
@CodesInChaos-因为没有客户端可以信任。攻击者可以通过完全绕过客户端来跳过整个缓慢的过程。您需要确保无法建立便宜,快速的哈希值的彩虹表。如果对每个盐都加盐并且中间哈希足够长,这是不可行的。否则,您只需制作一个哈希表彩虹表,如果它们很便宜,则可以非常非常快的速度生成哈希表。
– AJ亨德森
2014年8月5日14:08
同样,当我们讨论诸如POST与GET之类的问题时,请确保实现前向保密性,以便以后获得服务器私钥的人无法解密您的安全会话。
– Craig
14年8月5日在16:20
#2 楼
不一定。您还需要确保以下内容:
您的站点受到保护,以防跨站点请求伪造。使用同步令牌模式。
您的站点受到了会话固定攻击的保护。在登录时更改会话ID。
如果使用会话cookie,则您的整个网站都是HTTPS,而不仅仅是登录URL,并且您的会话cookie被标记为安全且仅使用http(否) JavaScript访问)。如果用户键入
http://yoursecuresite
(在同一浏览器会话中),浏览器将发送未加密的会话cookie。您正在使用最新协议。 SSL 1和2损坏,而3可能也损坏。尝试使用TLS 1.3。
您正在使用强密码。
您未在使用HTTP压缩(GZip)或TLS压缩。如果您的站点显示用户输入(例如搜索输入),那么如果您使用压缩,那么我可以找出您的CSRF令牌和银行帐号。
您的服务器不允许不安全客户端重新协商。
您正在使用2048位RSA密钥(或EC密钥的等效密钥),而且没人知道您的私钥。
您正在使用HSTS,因此即使用户键入http
,浏览器也可以直接转到https
您正在使用完全前向保密性,因此即使您私钥泄露
评论
如果整个网站都是https,我是否仍需要标记为安全的cookie?由于TLS层,它们仍将“免费”加密,对吗?
–埃米利亚诺
2014年8月4日在22:11
您能解释第6点吗?为什么压缩会使连接的安全性降低?
–埃米利亚诺
2014年8月4日在22:13
是的,您仍然需要安全的cookie(仅http),因为即使没有,它仍然可以被窃取。参见xss。压缩会杀死加密。请参阅BEAST和CRIME攻击。
–尼尔·麦圭根(Neil McGuigan)
2014年8月4日23:17
@Emiliano:即使您的站点仅是HTTPS,攻击者也可以在中间攻击中设置一个人,并设置一个使用纯HTTP的伪造服务器,执行称为SSL剥离的操作。浏览器会将用户的cookie发送到假服务器。为了减轻这种情况,您需要安全cookie和HSTS策略。
– Lie Ryan
14年8月5日,0:01
9.使用PFS来减轻某人(例如某些邪恶的政府)窃取您的私钥的风险。
– FooF
2014年8月5日在12:12
#3 楼
只要您验证证书的有效性,就可以很好地完成此操作。#4 楼
通常被认为是安全的大多数站点都采用了您所描述的方法。换句话说,您只是描述了已建立的行业标准。我建议您不要使用一种比您提到的安全性低的方法。 (我不会讨论bcrypt是比其他加盐哈希好还是坏的讨论。只是不要使用比加盐哈希更弱的东西。)
如果您想区分自己具有高于既定行业标准的安全性,还有其他选择。但要在应用程序的所有方面都付出巨大的努力才能使其物有所值。
关于密码验证的更为安全的领域包括:
保护通过在验证过程中将大部分计算分担给客户端,服务器可以抵御DoS攻击。即不要在服务器端迭代哈希,而仅在客户端端迭代并在服务器上执行哈希的最后一步。
如果通过从密码派生公钥对破坏服务器,则可以防止密码泄漏,并且永远不要让服务器请参阅密码或密钥。
#5 楼
正如其他人所说,这是一种标准方法。但是,对于个人网站,我不一定会遵循它...我会使用来自Facebook,Google或类似的联盟登录方式,因此不必处理帐户生命周期问题,并可以使用Google 2 factor Auth等。
它可以节省数据库中很多表格和字段的数量,从而减少出错的机会。
当然,您仍然需要通过身份验证提供程序的功能(例如Facebook组,允许的用户白名单或批准)授权希望访问的用户工作流程从您的帐户中删除。有时,这是通过邀请用户来完成的:为他们提供包含唯一安全代码的URL,并且您的系统在首次登录时将其链接到Auth提供程序。或者,用户进行身份验证并请求访问权限。这使它们处于“挂起”状态。然后,您提供一个界面,您可以在其中登录和批准它们。
评论
有点我不希望所有人都加入:我只想授予某些用户(例如我的朋友)的许可。
–埃米利亚诺
2014年8月5日19:34
是的,您需要仍然允许的电子邮件列表。然后,您根据联合ID进行检查。
– Andy Boura
2014年8月5日19:37
嗯,所以我可以实施白名单,是什么意思?很有意思,我也会研究这种方法。
–埃米利亚诺
2014年8月5日19:58
那就对了。您甚至可以使用您的Facebook朋友列表或群组进行Auth,但我不知道如何执行此操作的详细信息。
– Andy Boura
2014年8月5日19:59
添加了更多授权信息以进行回答。
– Andy Boura
2014年8月6日19:29
#6 楼
HTTPS使身份验证请求在传输过程中不可嗅探。但是,要使其“安全”,还需要采取其他措施。例如:整个登录页面及其所有依赖项也应该已经通过HTTPS提供服务,即使那时没有传输密码。通过未加密的HTTP服务它的任何部分(例如JavaScript,CSS或图像资源),将使攻击者能够通过中间人攻击来修改登录页面的外观或行为。
浏览器将以不同程度的怀疑对待混合的HTTP / HTTPS内容。有些人只会在UI中隐藏the“锁定”图标。更多偏执的浏览器将拒绝完全加载未加密的依赖资源。无论哪种方式,都应通过HTTPS提供整个登录页面。
不要在HTTP GET的查询字符串中提交密码。通常将Web服务器配置为记录请求的URL,其中将包括URL的查询字符串部分。将密码放在POST正文中。 (您也可以使用RFC 2617 HTTP身份验证,但注销支持参差不齐。)
评论
是的,我一直记得GET是一个坏主意,因为它在客户端系统上可见,并且可能会出现在客户端历史记录中,但是忘记了服务器也可能会记录参数。
– AJ亨德森
14年8月5日在16:41
#7 楼
Wikipedia拥有完整的HTTPS历史性安全问题页面。HTTPS安全性漏洞以前已经发生过(为什么两个较旧的版本都被破坏了?什么是“失败”?什么是“ https怪胎”? )。
我不建议放弃HTTPS,但在大多数情况下在其下放一些东西不会造成任何危害。如果您已经可以通过该通道发送未加密的密码,则可以发送任何您想要的内容。
评论
为了增加您已经收到的答案,在这种设置中,我建议您查看证书固定,以帮助缓解MITM攻击...也许考虑对密码进行哈希处理,而不是对密码进行加密(或除了加密之外)。
即使使用https可能很安全。我在其他问题中读到的一个问题是,如果直接在url中传递用户名和密码,它将被写入服务器日志。如果日志安全性受到威胁,可能会很危险。