我们正在迁移基于MVC的服务器应用程序,并制作一个REST-ful API,通过它来处理调用。
我一直在阅读关于AES加密和OAuth2的内容,并决定实施以下概念的解决方案:
所有通信都是通过TLS处理的,因此这增加了安全性,而不是唯一的防线。
在移动应用程序上,这可以工作,因为你可以在配置文件上隐藏移动应用程序的密钥,这提供了一些体面的安全措施 - [也许不是很多我不完全确定]但是如果我们尝试转换从我们的网页到此表单的所有请求,这将意味着使用Javascript来处理客户端AES加密和身份验证,并且...... well as this article clearly explains,“如果您将API密钥存储在JavaScript Web应用程序中,那么您也可以只需在主页上用粗体字母打印出来,因为整个世界现在可以通过浏览器的开发工具访问它。“
我只能使用nonces作为API密钥 - 或者完全放弃对这些请求使用AES加密,并尝试通过其他方式验证,例如CSRF令牌,并确保所有请求都来自我们自己的前端方式 - 但如果我们想创建一个允许与其他页面或服务集成的API,那么这将无法工作,即便如此,我将如何保护客户端的秘密会话密钥?
文章建议将一次性使用的Cookie作为代币生成,但这是一种有限的解决方案,适用于海报的服务但不适合我们。我希望HMAC能够向用户发送的每个请求都使用特定于用户的密钥,该密钥可能会过期并被重置,并且由于该服务最终会处理资金,我希望请求身份验证被锁定。
那么我的选择是什么?
我是否因为它is doomed而放弃了Javascript?有没有办法存储一个秘密密钥,而不会在将其硬编码到.js脚本中时将其暴露出来?我应该生成一个新的临时密钥,仅用于登录呼叫,并在请求服务器现时将其发送给用户吗?
此外,我首先链接的帖子建议使用cookie来存储客户端的Session密钥,然后从JS访问密钥。这样可以,还是会提供比密封更多的孔?
答案 0 :(得分:2)
了解哪些措施可以防止哪些安全漏洞,这很好。
JavaScript是不正确的,因为没有地方可以存储密码。还没有好的加密库,因为你不应该用JavaScript加密。
会话密钥可以用作身份验证密钥。如果您使用TLS,则您的连接是安全的,并且攻击者无法知道会话密钥。 此外,JavaScript不需要知道会话密钥。默认情况下,Cookie会随每个请求一起发送。您可以将cookie设置为仅限http的cookie。您不必必须执行此操作,但它会添加另一层安全保护。
您可以为会话cookie提供非常长的到期时间,以便它基本上像秘密API密钥一样工作。浏览器将负责安全地存储cookie。建议经常轮换会话密钥,通常是在每个新会话开始时以及身份验证信息发生更改时(如密码重置)。
CSRF令牌可防止重播攻击。它绝对建议使用CSRF令牌保护修改请求。您不需要对每个请求进行CSRF检查,只需要修改敏感信息(例如您的登录凭据或您的情况:交易)的请求。 对于CSRF令牌,您可以使用与会话密钥相同的方法:将其存储在cookie中。
关键部分是JavaScript并不需要知道任何这些。
我确信您也意识到的一件重要事情是,您生成的任何密钥或随机数必须是加密安全的。不要使用低熵函数。
所以:
您不需要加密用户ID或电子邮件,TLS已经为您做了。此外,您也可以发送密码,不需要在步骤3中单独发送密码。我们不会在JavaScript中进行任何加密。所有加密仅由TLS / HTTPS处理。
如果您有一个单独的身份验证服务器(如单点登录),这种方法很好。否则,您可以跳过此步骤。
你不需要这个。
服务器不需要解密任何东西,加密由TLS处理。你如何存储密码是一个自己的主题,但我认为你已经得到了它。
确定。同样,客户端不应该加密任何东西。
只发送会话密钥。这已经足够了。
修订是:
客户端发送登录凭据。连接必须安全。
服务器验证凭据并将身份验证令牌作为cookie发送,并跟踪身份验证令牌是会话列表。
对于每个请求:
客户端包含身份验证令牌。如果您使用cookie,则会自动发生这种情况。
服务器验证身份验证令牌,并可能生成客户端将在此时使用的新令牌。
答案 1 :(得分:1)
移动应用应被视为public clients。这意味着他们不应该存储任何秘密。无论您使用何种加密算法,都不会阻止客户端凭据受到损害。
这就是OAuth2 Framework协议定义允许公共客户端交互并且不需要任何客户端身份验证的Implicit grant type流的原因。您还可以考虑使用RFC7636来保护访问令牌的发布。