代码之家  ›  专栏  ›  技术社区  ›  appa yip yip

“安全”存储(在客户端)令牌以供重用?

  •  3
  • appa yip yip  · 技术社区  · 6 年前

    我正在尝试创建一个桌面应用程序,它将向我正在开发的web服务发送更新。

    理想情况下,应用程序只配置一次并部署到网络共享。配置应用程序时,用户将输入用于在web服务中进行身份验证的密码。之后,将创建一个令牌,用于将来的连接。

    这将允许任何有权访问网络共享的计算机(即使它不是配置应用程序的计算机)只运行应用程序(将连接到web服务),而不输入任何凭据(因为令牌已保存)。

    问题是: 我该如何保护这个代币?

    • 我知道存储它的客户端永远不会是完全安全的,但是我想让某人尽可能难以访问明文令牌。
    • 我正在寻找一个答案,最好不依赖于任何操作系统资源(因为应用程序可以从不同的设备执行)。
    • 假设我完全控制了应用程序和web服务器
    • 我正在使用C#开发控制台应用程序,但我认为这更多是一个理论问题(与任何特定语言无关)

    以下是我尝试/思考过的一些事情:

    • 使用类似C#的东西序列化令牌 SecureString 并将其存储在文件中 :这是我带的最好的。但是很明显,如果有人获得了对密钥文件的访问权,那么逆转是非常简单的。

    • This 答案建议使用 Windows Data Protection API (DPAPI) (在C#中 ProtectedData 但显然,这只允许最初保存凭据的用户访问它们,这不起作用,因为我必须从多个用户/设备访问受保护的数据。

    • 将令牌作为参数传递给应用程序 :这只是改变 哪里 我将存储令牌(例如,在调用程序的批处理文件或操作系统任务上),但我认为这不会使它更安全。

    5 回复  |  直到 6 年前
        1
  •  1
  •   Simon Mourier    6 年前

    由于用户不是机器的管理员(这是一个基本假设),有很多方法可以对她隐藏东西。

    我的建议是:

    • 确保主应用程序在不同的凭据下运行,而不是 记录用户,一个“特殊用户”。
    • 编写另一个终端用户应用程序,仅用于安装,与此应用程序对话(使用任何您认为合适的进程间通信,TCPIP,无论什么,可能是安全的,但我不会太在意这一点)。此应用程序仅用于收集凭据并将其发送到第一个应用程序
    • 现在,主应用程序可以在登录用户无法访问的任何地方编写令牌,但我建议使用受保护的数据,因为它非常容易使用

    下面是一些图形说明:

    enter image description here

    因为数据是用受保护的数据加密的( Windows Data Protection )只能由已加密的Windows用户解密,登录的用户将无法读取“特殊用户”数据。

        2
  •  0
  •   birwin    6 年前

    我建议你用 JWT .

    成功验证后,服务器将生成令牌。令牌将被发送到客户端。对服务器的每个后续调用都会将头中的令牌发送到服务器。然后服务器将验证令牌。如果已验证,则服务器知道客户端已验证。

    不需要在客户端存储用户名/密码。

        3
  •  0
  •   martinstoeckli    6 年前

    没有防弹的方法可以解决这个问题,客户端最终需要访问服务器,因此攻击者可以在客户端上拥有足够的权限。

    您所描述的是 OAuth2 协议,因为你可以控制服务器。使用OAuth2,您不能避免在客户机上存储秘密的需要,但是通过将其交换为令牌,您可以保护原始密码,并且可以保证令牌非常强(用户密码往往很弱)。

    要在客户机上存储令牌/密码,可以在存储之前对其进行加密,但这会立即引发一个问题,即在何处存储用于此加密的密钥。攻击者可以从客户端提取。有一些方法可以提高密钥存储的安全性。

    1. 根据您的情况,您可以考虑使用 Hardware security module (高速行驶)。
    2. 您可以使用特定于操作系统的密钥存储,就像您在数据保护api中提到的那样。密钥存储只能帮助保护密钥, 因为 它有操作系统的支持(我想这就是你所说的独立性?)。使用DPAPI,您不仅可以限制对已登录用户的访问,还可以将其限制到本地计算机。密钥存储也可以在其他操作系统上使用。
    3. 用户可以在每次启动客户端时请求密码,而不是将密码存储在客户端上。这可以简化为启动设备,然后密码可以在内存中独占保存。
        4
  •  0
  •   Ricardo Gonçalves    6 年前

    好吧,你不能在客户端保护任何东西。一旦它在那里,任何有特权的人都可以看到它。

    你能做的就是让这条信息没有其他东西就毫无用处。

    最好的方法是存储 公钥 在客户端使用这个 公钥 创建哈希以通过webservice对用户进行身份验证。

    当用户配置应用程序时,服务器发送应用程序本地存储的公钥。当应用程序调用服务器时,它将使用此公钥和只有应用程序和服务器知道的私钥创建哈希。然后服务器可以使用其私钥检查哈希是否正确。

    为了提高安全性,您也可以在散列中使用时间戳,因此它将超时更改并防止密钥的重用。或者它可以发送一个新的 公钥 每个webservice的答案。

        5
  •  0
  •   Phathutshedzo Khabubu    6 年前

    我建议你用 IdentityServer4 由于它提供了符合RFC的协议,并且根据GrantType的不同,在桌面应用程序的上下文中提供了一个客户端应用程序。

    即使令牌是纯文本的,它也在webservice中受到保护,在webservice中,访问控制(令牌的颁发者)通过检查客户端请求中的源和存储在数据库中的源来验证令牌是从正确的客户端接收的。