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

时间:2010-08-17 13:13:35

标签: security authentication encryption cryptography

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

我有两个问题:

  1. 不创造是件坏事 我们自己的OpenID提供商和设置 我们的OpenID消费者只接受它吗? 公共登录或注册不是 允许,我们想保留 认证简单。

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

  3. 如果您作为公社可以批准此设计,我会考虑将此代码提取到Ruby on Rails插件中。

    请查看flowchart and sequence diagram

    详细说明:

    身份验证提供程序(“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漏洞。

4 个答案:

答案 0 :(得分:7)

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

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

  

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

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

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

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

答案 1 :(得分:4)

以下是关于问题1的一些快速想法:

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

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

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

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

  • 支持您的协议的一点是您花时间详细描述它。只是这样,你就比大多数自制的安全协议设计师都要高!

答案 2 :(得分:2)

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

那么什么是漏洞?

  

最终用户“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进行会话管理是另一种可能性。

答案 3 :(得分:1)

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

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

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