我目前正在构建一个通过Plaid使用Open的web应用程序。这意味着它通过生成的“访问令牌”来获取用户的银行详细信息。
我一直在玩如何持久化这个用户数据的概念。我的理由是,Plaid API会在每一个需要它的网页上被拉出来,所以它会导致几秒钟的“加载”--如果你在我的应用程序中导航,这是令人沮丧的。
在我看来,这是一个糟糕的用户体验,所以我更愿意在不需要进行服务器调用的情况下以某种方式保存这些数据。
为了做到这一点,我最初使用了会话存储。我知道很多人说这很容易受到诸如XSS等东西的影响,但是它很方便,而且工作也很好。
不过,出于显而易见的原因,我对在本地存储服务器调用的结果感到有点不安。
目前,在本地提取并因此存储的数据是:
还有一堆其他身份代码。
实际数据本身是不可识别的,也不能用于我所知道的任何恶意数据。没有在本地存储密码,访问令牌只能通过我的服务器进行交换,而且它是加密的,因此如果我的数据库遭到黑客攻击,就不可能公开显示为纯文本。
所以我想我的问题是,这有多安全?考虑到数据不能显式地用于恶意目的,这实际上是一个安全问题吗?唯一的问题(在我看来)是如果我的服务器/数据库被加密密钥访问的话。
其他的选择是..。
或者有人能提出其他选择吗?
我知道这里的人在这方面会比我有更多的经验--所以对任何建议都是开放的。请告诉我,我会很感激的。
发布于 2021-01-23 07:20:33
您正在将潜在敏感的用户数据存储在浏览器、客户端,并不时引用这些数据。我将使用经过身份验证的对称密码来存储这些信息,它(取决于您的密钥管理工作方式)为机密性和完整性提供了强有力的保证。通过以下方式使用数据:
在前两种情况中,您从来没有在客户端解密的要求--您基本上依赖于客户端来可靠地存储会话数据。我假设您不在第一个场景中,因为您将进行一个服务调用来获取Plaid数据(基本上是您想要避免的!)我还假设密钥管理策略代码不能被干扰(.如果你打算在客户端解密的话.(稍后再详细介绍)。
我建议您为每个客户创建输入密钥材料,例如,将其赋于cookie。( cookie可能是一个很好的选择,因为用户可能对cookie销毁有更严格的规则。)另一种选择是将会话密钥材料存储在http服务器或数据存储中。我不会用加密的会话数据来存储它。客户端提供来自本地存储的加密会话数据以及它持有的任何input_key_material,然后服务器将根据需要派生关键材料。
您将使用经过身份验证的对称密码:使用关联数据进行身份验证加密。最好是像X/ChaCha20Poly1305或AES-GCM这样的东西可以胜任这项任务,但是,您可能需要咨询任何治理或立法约束(例如。有些标准将您的选择限制为AES-GCM和SHA2)。
一般来说,这个密码遵循定义:AE( key , nonce , plain_text , assoc_data ),其中plain_text是您想要加密的数据,assoc_data是额外的明文数据,不会加密,但必须经过身份验证。
至关重要的是,如果plain_text或assoc_data发生了变化,那么nonce和/或key也必须改变。如果代码导致对两个不同的key + nonce值进行plain_text重用,则两个密文的XOR将与两个明文的XOR相同。这可能导致数据泄漏,特别是在已知格式的情况下。
防止当前重复使用的一种常见方法是,如果计数器小于16字节,则使用计数器;如果计数器小于16字节或大于16字节,则使用随机值(__TODO ref)。这将取决于您为AE使用的密码。在前一种情况下,我过去使用过的一个解决方案是生成一个8字节的特定于客户端会话的前缀,然后从时代时间获取4个字节。客户端保存包含4字节定时器值的input_key_material,而前缀(以及键)则根据需要在服务器上计算,并在使用后立即处理。定时器的选择是相对安全的,因为任何对手都会捕获数据包的定时。(一旦您考虑了所有这些,您可能会分别询问一个潜在的解决方案。)
这里的基本问题是安全地向客户端传递代码和密钥。如果你在这个网站上搜索,就会有很多讨论权衡利弊。最近有一个WebCrypto API将限制您的AES-GCM和SHA2。你将需要一个“好的方式”,以获得关键材料的浏览器。
就我个人而言(在写作的时候),我也没有强烈的意见。您可以使用可用的工具并承担风险。我会在第三方Javascript执行.sodium.js)上使用内置的浏览器API,因为我的工作假设浏览器中的实现(不能被其他javascript代码偷偷替换)的可塑性较差。
https://security.stackexchange.com/questions/243707
复制相似问题