使用自定义API保护客户端上的API机密


Securing API Secrets On Clients Using Custom API

我正在使用Phonegap/Cordova编写一个移动应用程序。移动应用程序需要来自服务器端应用程序的信息,这是我编写的。我创建了一个API来获取这些信息。

API做的第一件事就是验证移动应用程序是我编写的应用程序。它使用一个公共的API密钥和一个秘密的API密钥来实现这一点。(它们用于生成授权标头)。

授权头在移动应用程序和服务器端应用程序上生成,服务器将相互检查是否存在差异。

它是这样的:

移动应用程序(Javascript/jQuery)

var SIGNATURE = SHA512( MY_APP + MY_PUBLIC_API_KEY + TIMESTAMP + NONCE + MY_SECRET_API_KEY );
var auth = "path=MY_APP,key=MY_PUBLIC_API_KEY,time=TIMESTAMP,nonce=NONCE,signature=SIGNATURE"
$.ajax( { 
    type = "POST", 
    url: url, 
    headers : {
        "Authorization" : auth
    }
} );

服务器端(PHP)

// there is some regex to "decode" the auth header
// now, recreate the signature from the public variables in the auth header and check for a match (note: this includes fetching the secret from an xml file as it is not in the public information)

问题显然在于我需要秘密的API密钥来在客户端生成签名。

在网上阅读文章后,很多人都说要将秘密存储在服务器上(然后将服务器作为中介),但我相信这只适用于使用第三方API的情况。这也只是将问题从客户端转移开。是什么阻止了某人打电话给中介,而中介无论如何都会把秘密保密?

一个非常相似的解决方案是将机密存储在服务器上,并在应用程序加载时获取,但这肯定是同样的问题。。。是什么阻止了一个人简单地去api.mydomain.com/getsecretkey

在客户端存储机密是不可行的。尤其是电话间隙。那么人们是怎么做到的呢?

感谢您的任何帮助。

我认为这里的底线只是:"你做不到。"这项工作是在用户的机器上完成的,使用机器上也存在的代码。因此,一个意志坚定的小偷可以洞悉你所有的"秘密",而你对此无能为力

可以向主机添加各种形式的检查,只需查找每个请求中所需的内容,并在不存在此特征的情况下拒绝响应(甚至"丢弃数据包")。例如,这将允许您忽略一些脚本孩子的机器人向您抛出的"垃圾"请求:;他们必须拥有你的客户端应用程序的副本,才能弄清楚如何正确地表达他们的消息,这自动意味着"一个更坚定、更不随意的小偷"

在服务器上,您可以首先检测您的"身份验证"数据,如检查所需的基本数据、用户代理等。

其次,尝试加密您的数据,您可以先使用应用程序密钥为服务器获取新密钥(用于下一个会话),然后使用重新发送的新密钥作为下一个加密密钥。
建议端到端加密。

JWT.io库可能有助于解决这些问题。https://jwt.io/

如果不满足这些要求,服务器可能会拒绝连接或发送错误代码。