如何保护调用 API 的桌面应用程序?

How can I secure my desktop app calling my API?

客户使用我的桌面应用程序。客户是拥有许可证密钥及其计算机的 MAC 地址的用户。桌面应用程序只能在一个实例上使用。

所以当用户购买许可证并注册时(意味着他下载、打开桌面应用程序、输入并提交他的许可证密钥),我将首先检索他的 MAC 地址然后执行 POST 以这种方式向我的 API、/user 请求参数 {license-key: "license_here", mac-address: "mac_here"} 所以这些被保存到我的数据库中。

现在,一旦用户注册,我应该如何保护桌面应用程序中的 API 调用?

假设用户想要访问他的设置选项卡,我是否应该向 GET 请求提供 {license-key: "license_here", mac-address: "mac_here"} 作为参数并检查它是否与他的许可证密钥和 MAC 地址匹配我的数据库,如果有,在设置选项卡上显示他从数据库中检索到的所有设置?

或者有更安全的方法吗?

我认为的另一种方法是 hash 许可证密钥和 MAC 地址,concat 它们并使用我将用于每个请求的身份验证令牌.

我正在使用 API 而不是在本地保存,因为我将在完成桌面应用程序后创建一个移动应用程序,并且我需要在两个应用程序之间共享信息。

NodeJSExpressMongoDB/Mongoose 结合使用。

您正在尝试使用只有它拥有的一些 data/knowledge(它的 MAC 和许可证密钥)来验证计算机。这很容易绕过,因为未经许可的计算机可以欺骗数据并使您认为请求来自经许可的计算机。如果您只传输 license/MAC 数据,那么任何其他知道的计算机也可以通过拦截单个请求来模拟许可计算机 - 模拟所需的所有信息都包含在请求中。

如果没有专门的硬件,您就无法保证计算机的唯一性。这通常采用包含密钥或证书的专用微芯片的形式。无法从芯片中读取数据,但可以使用芯片创建数字签名。

如果没有专用硬件,您能做的最好的事情就是为每台计算机使用唯一的许可证密钥,并要求所有请求都是 signed using this key。这依赖于密钥的私密性(签名随消息一起发送,而不是密钥本身)并且不能保证,因为您不控制客户端计算机。

编辑 - 工作原理:
向每个客户端颁发许可证密钥。在您的服务器上,记录您根据分配给它的计算机的 MAC 地址发出的每个密钥。您可能应该在颁发许可证时收集 MAC 地址。不要让客户获得 'register' 他们的许可证。客户端必须使用密钥对他们发送的每个请求进行签名,并在每个请求中包含签名和 MAC。在服务器上,您通过使用 MAC 地址查找密钥并自己重新创建签名来验证每个传入请求。如果签名与客户提供的签名相符,那么您就知道它是真的。请记住 - 这仍然不是万无一失的!我可以从您那里购买一个许可证并将其安装在任意数量的计算机上,只要我让它们都伪造已批准的 MAC 地址即可。我也可以把我的钥匙给我的朋友,让他们也伪造 MAC 地址。