繁体   English   中英

你能发现我的身份验证协议中的漏洞吗?

[英]Can you spot a vulnerability in my authentication protocol?

前段时间我们需要一个多个Web服务之间的单点登录身份验证解决方案。 至少在那个时候我们认为OpenID协议过于复杂,我们不相信它的Ruby on Rails插件。 因此,我们设计了自己的协议,而不是实现OpenID提供者和OpenID使用者。

我有两个问题:

  1. 不创建我们自己的OpenID提供商并设置我们的OpenID消费者只接受它是不是一件坏事吗? 不允许公开登录或注册,我们希望简化身份验证。

  2. 您能否在以下设计中发现关键错误或漏洞?

如果你作为一个公社可以批准这个设计,我会考虑将这个代码提取到Ruby on Rails插件中。

请查看流程图和顺序图

细节:

身份验证提供程序(“AP”):

  • 中央服务,包含有关用户的所有数据。
  • 此设置中只存在一个“AP”。
  • 有可能有多个“AP”,但在这种情况下这不应该是相关的。
  • “AP”事先知道每个“S”。

身份验证客户端(服务“S”):

  • 存在多个内部和外部Web服务。
  • 每个服务事先都知道“AP”及其公钥。

演员(“A”):

  • 通过用户名和密码使用AP对自己进行身份验证的最终用户
  • 可以在登录前直接请求任何“S”或“AP”URI

“A”,“S”和“AP”之间的连接由HTTPS保护。

简要描述了认证逻辑:

这些是对本文顶部链接的图形流程图和序列图的描述。

1)Auth Provider“AP”

  • “AP”向“S”发出服务器到服务器HTTP POST请求以获取现时。
  • “AP”生成身份验证令牌。
  • 身份验证令牌是一个XML实体,包括:
    • 到期日(从现在起2分钟),
    • 先前请求的随机数(以防止重播),
    • 识别“S”的名称(Service_1的令牌不适合Service_2),
    • 有关最终用户的信息。
  • 身份验证令牌使用AES256加密,加密密钥和初始化向量由AP的私有RSA密钥签名。
  • 产生的字符串(“data”,“key”和“iv”)首先进行Base64编码,然后进行URL编码,以允许它们在URL查询字符串中传递。
  • 最终用户“A”被HTTP重定向到服务“S”(HTTPS GET请求)。

2)服务“S”

  • 从用户代理接收URL参数中的身份验证令牌。
  • 使用AP的预共享公钥解密身份验证令牌。
  • 仅接受一次身份验证令牌(令牌包含仅一次有效的nonce)。
  • 检查身份验证令牌中的标识名称是否与服务名称相对应。
  • 检查身份验证令牌是否已过期。

备注:

如果其他人也可以解密身份验证令牌,这不是问题,因为它不包含有关用户的机密信息。 但是,除AP之外的其他任何人都无法生成有效的身份验证令牌。 因此涉及RSA密钥对。

RSA私钥仅用于对令牌进行签名,因为它无法加密比实际密钥长度更长的数据。 因此,AES用于加密。

由于身份验证令牌是作为HTTP GET请求传递的,因此它将存储在例如Apache的日志文件中。 使用一次性随机数和失效日期应尽量减少重放攻击的可能性。 POST请求需要一个HTML页面,其中包含由Javascript自动提交的表单,这就是使用GET的原因。

服务“S”仅在服务器到服务器API请求中生成随机数。 因此,未经身份验证的生成请求不应构成DoS漏洞。

您会混淆身份验证(“我就是我说的是我”)和授权/访问控制(“我可以访问它”)。 您只需实施OAuth,然后通过HTTPS查询服务器“是否允许此OAuth身份访问我?”。 您不必担心重放攻击,因为您使用的是HTTPS。

“安全很难,所以我会自己设计。”

身份验证令牌使用AES256加密,加密密钥和初始化向量由AP的私有RSA密钥签名。

AES-256和AES-192具有弱密钥时间表。 但你不是用它来保密; 你正在使用它作为某种“完整性”检查。 它不起作用:攻击者获得“签名”身份验证令牌。 攻击者恢复了密钥和IV。 攻击者使用相同的密钥和IV加密不同的身份验证令牌,并使用相同的“签名”。

散列它并签署哈希有什么问题? 另请注意,如果您要使用自定义签名,则需要注意填充(IIRC PKCS-无论添加至少11个字节)。

编辑:如果您使用的密码应该使用散列/ MAC,那么您真的不应该设计安全协议!

以下是关于问题1的一些快速思考:

  • 设计一个有效的安全协议是非常困难的,所以基于一般原则,我倾向于使用现有协议。

  • 但是,我很欣赏OpenID当时可能还不是很成熟。 此外,OpenID仍然相对较新,可能尚未解决所有限制。

  • 尽管如此,你仍然在一个受限制的情况下使用OpenID,其中OpenID的大问题(多个参与者的参与)没有发挥作用。 您只使用OpenID的“技术核心”,这更容易理解。

  • 您的要求和协议概述让我想起了Kerberos。 我也很想推动LDAP +单点登录,但我不知道具体的解决方案是什么。

  • 赞成你的协议的一点是你花时间详细描述它。 只是这使你超过大多数自制的安全协议设计师!

简而言之,我发现这个协议在错误的地方过度设计,最终容易受到攻击。

那么什么是漏洞?

最终用户“A”被HTTP重定向到服务“S”(HTTPS GET请求)。

这很可能违反了OWASP A9 用户的会话ID在任何情况下都不能通过不安全的通道(例如http)传递。 即使会话ID尚未经过身份验证,攻击者仍然有耐心,他可以嗅探线路查找会话ID,然后定期检查它们是否已经过身份验证,然后使用它们访问您的系统。

“复杂性是安全的最大敌人。”

- 布鲁斯施奈尔

身份验证令牌使用AES256加密,加密密钥和初始化向量由AP的私有RSA密钥签名。

首先,RSA可用于加密消息,因此不需要。 另一方面,HTTPS将更有效并且被证明是安全的。 当您已经拥有安全的服务器到服务器通信通道时,我不明白为什么必须将身份验证令牌传递给客户端。 服务器可以说“嘿,有人被重定向到这个会话ID,他的状态信息是什么?”。 这是链条中最薄弱的环节,你的会话ID应该足够强大。 这将要求客户端在发生切换时发送会话ID作为GET或POST请求,这可能会打开Session Fixation的大门。 您可以在切换之前和之后检查IP地址,有时客户端的IP地址可以合法地改变,但是切换将是一个非常狭窄的窗口,在这种情况下可以发生这种情况,最重要的是它会完全停止会话固定。

一般来说,你应该避免重新发明风团。 特别是当涉及到这样已经解决的安全问题时。 如果您需要绑定非http身份验证,Kerberos非常漂亮。 使用LDAP进行会话管理是另一种可能性。

你真的只是签署AES密钥,然后发送加密令牌,密钥的RSA签名,然后在PLAINTEXT中发送key-iv?

这是一个失败。 攻击者可以使用此密钥解密令牌,以任何需要的方式更改它并加密回来。 您的服务器永远不会发现差异。

如果要检查令牌完整性,只需对其进行哈希并对此哈希进行签名即可。 这就是哈希所用的。 这里不需要使用加密。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM