PHP - 在两台服务器之间安全地发送请求/响应?

时间:2013-05-21 16:00:43

标签: php api security post

要点: 我用PHP创建了一个应用程序。它是呼叫中心的主管系统。我现在需要允许合作伙伴通过将我们的应用程序与其专有CRM集成来为应用添加新的潜在客户。简而言之,我想我需要为我的应用程序构建一个API。

我能想到的最简单的方法是一个简单的HTML帖子。这会被认为太不安全吗?如果是这样,对于这种情况最好的办法是什么?

感谢您的帮助,

安德鲁。

3 个答案:

答案 0 :(得分:6)

通过构建API的过程,您很可能会遇到其中一些问题。我将概述可能非常方便实际构建可用的API的概念,并遵循开放标准(反过来,这使得第三方调整现有代码与之交互变得微不足道)

API处理

第一个关键字是:SSL。永远不要想到不使用它。这提供了一个安全的套接字层,可以以安全的方式进行通信,从而使窃听和MitM攻击更难以构思。

无论如何,不​​要跳过这个。证书的成本低于每年60美元,所以它的成本并不高,从长远来看可以为您节省很多。

就服务器技术而言,使用您想要的。您的主要要求是可以处理四个常见HTTP谓词的Web服务器:GET,POST,PUT,DELETE。我马上解释一下原因。

API授权

这是一个充满争议的领域,因为很多人“认为他们有一种安全的方式”。答案是不正确的。您的身份验证的目的是允许客户端使用其凭据轻松进行身份验证,但是为了防止没有特权的第三方这样做。

简单地向Feed添加API密钥只会导致某人最终获得它。我已经多次看到这个特定的东西,我强烈反对它,特别是因为有更容易的选择。

我将介绍一些事项,分别将它们标记为(A)(S),分别用于身份验证和签名。签名是用于呈现您的请求防篡改的方法。身份验证证明你是谁。

HMAC-SHA512签署(A)(S)

Amazon使用此技术来处理所有S3 / AWS API,这是一种非常轻量级的签名和身份验证请求方法。我个人觉得它比较巧妙。

基本理念:

  1. 汇总所有GET和POST字段(包括您的公钥)
  2. 按字母顺序排序
  3. 使用URLEncode或等效的
  4. 连接它们
  5. 使用您的私钥作为HMAC的密钥,对数据执行HMAC哈希密码。
  6. 将结果4附加到您的请求中。
  7. 这很简单而且很巧妙。它保证的是什么:

    1. 如果不知道私人和公开
    2. ,则无法更改请求
    3. 您无法在不更改请求的情况下更改密钥
    4. 这使用相同的HTTP请求整齐地包装两个问题,代价是一个保留的GET / POST字段。亚马逊还要求请求中存在时间戳,以防止重放攻击。整齐!

      (参考:HMAC- ALGO = ALGO( (key XOR PAD) concat ALGO(key XOR PAD2) concat message) ALGO 可以是任何哈希密码 - SHA256因其轻量级特性而首选

      OAuth(A)

      你可能听说过它。这个想法很简单:给你一把钥匙和秘密。这允许您排队等待临时令牌。然后,此令牌用于执行请求。

      这样做的主要优点是存在大量用于处理它的库,包括客户端和服务器端。另一个优点是OAuth有两种操作模式:双腿(服务器 - >没有客户端交互的服务器)和三脚(客户端 - >服务器 - >服务器)。

      主要缺点是获取令牌的2个HTTP请求。

      只需通过(A)

      发送私钥即可

      ......导致重播攻击。不要考虑它。

      方法的混合是可能的事情。例如,与OAuth结合使用时,HMAC标牌非常棒!

      API概念

      现在的API端点遵循两个主要标准:SOAP(XML-RPC)或REST。如果您要构建一个端点来发布潜在客户,您也可以构建相应的API来阅读潜在客户并在将来删除它们。

      因此,您的API采用以下形式:

       /my/endpoint/
        - GET: gets a list of leads
        - POST: creates a new lead
       /my/endpoint/ID/
        - GET: get lead info
        - PUT: modifies lead
        - DELETE: deletes the lead
      

      这使您可以方便地为您的API提供面向未来的保证。

答案 1 :(得分:1)

HTML帖子就足够了,这不是问题。如果您能够使用HTTPS来确保传输的数据是经过编码的,那就更好了,但这并不重要。

确保此类API的最常见方法是提供共享的秘密'或' key',用于编码哈希。然后,您将能够验证请求是否来自受信任的来源,但是由用户决定是否保密共享密钥。

e.g。您API的用户需要:

// build hash string to be sent with API POST request (use a sensible combination of values)
$string = sprintf('%s.%d.%d.%d', $username, $orderId, $currentTimestamp, $price);

// hash
$encodedString = sha1($string);

// concatenate with shared key
$stringWithKey = sprintf('%s.%s', $encodedString, $sharedKey); // GET KEY FROM SECURE PLACE

// hash again to get hash that will be sent with the POST request
$hash = sha1($stringWithKey);

然后,您将根据提供的POST值在您的最后执行相同的逻辑,并验证它们的哈希值与您使用用户的共享密钥构建的哈希值匹配。

答案 2 :(得分:-2)

这正是API的用途。我会为每个外部帐户创建一个唯一密钥,并且需要为发送到您服务器的每个$_GET$_POST交易提供API密钥。

可能希望在您使用时构建API管理控制台。哦,不要忘记API密钥的单独数据库表。

当你完成它之后会像:

https://api.mysite.com/index.php?key=r328r93fuh3u4h409890fj34klj&other=something&another=somethingelse

你明白了。