delatbabel/apisecurity

API安全助手。

v1.2 2016-01-27 05:05 UTC

This package is not auto-updated.

Last update: 2024-09-11 22:38:24 UTC


README

Build Status StyleCI Latest Stable Version Total Downloads

API安全助手是为API连接的安全设计的,通常用于REST或其他基于HTTP的API,其中认证过程通常涉及共享密钥,可能是一个公私钥对,而不是在Web应用中更常见的用户名/密码/cookie类型的安全。

最近更改

v1.0

首次稳定版本。

v1.1

增加了缓存和非ces的验证(服务器和客户端)。

v1.2

增加了一个新的密钥生成类来生成和存储共享密钥。现有的密钥类(用于处理公私钥对)已重命名为KeyPair -- 所以如果你直接使用该类,则应使用KeyPair而不是Key。

特性

  • 构建加密非ces
  • 构建公私钥对
  • 签名API请求
  • 验证API请求的签名

安装

composer require delatbabel/apisecurity

完成这些后,运行composer update命令

composer update

示例

简单的客户端或服务器端nonce生成

// Generate a nonce
$nonce = new Nonce();
echo "Nonce is " . $nonce->getNonce() . "\n";

签名计算(客户端)

签名使用RSA密钥对。要生成签名,需要知道密钥对中的私钥。

$client = new Client();
// $private_key_data can be the file name of the private key or the text of the key itself.
// This should be known only to the client.
$client->setPrivateKey($private_key_data);
$client->createSignature($request_data);

将生成并存储客户端nonce作为 $request_data['cnonce']。将生成并存储签名作为 $request_data['sig']

HMAC计算(客户端)

HMAC使用共享密钥。

$client = new Client();
// $shared_key_data can be the file name of the shared key or the text of the key itself.
// This should be known to both the client and server.
$client->setSharedKey($shared_key_data);
$client->createHMAC($request_data);

将生成并存储客户端nonce作为 $request_data['cnonce']。将生成并存储HMAC作为 $request_data['hmac']

签名验证(服务器)

验证签名需要知道客户端的公钥。

$server = new Server();
// $public_key can be the file name of the client's public key or the text of the key itself.
$server->setPublicKey($public_key);
$server->verifySignature($request_data);

如果签名无效,将抛出SignatureException。

HMAC验证(服务器)

验证HMAC需要知道共享密钥。

$server = new Server();
// $shared_key can be the file name of the key or the text of the key itself.
$server->setSharedKey($shared_key);
$server->verifyHMAC($request_data);

如果HMAC无效,将抛出SignatureException。

服务器nonce生成(服务器)

这一步是可选的,并将特定请求与客户端的IP地址关联起来。这需要额外的API调用,如下所示

    Client                           Server
      |                                |
      |   Request server nonce         |
      | --------------------------->   |
      |                                |
      |   Server nonce provided        |
      | <---------------------------   |
      |                                |
      |                                |
      |   API call including snonce    |
      | --------------------------->   |
      |                                |
      |                         Verify |
      |                                |
      |   API response                 |
      | <---------------------------   |
      |                                |

在服务器端,可以使用实现\Delatbabel\ApiSecurity\Interfaces\CacheInterface的任何类来创建或验证nonce。在\Delatbabel\ApiSecurity\Implementations命名空间内提供了两个参考类

  • LaravelCache -- 使用Laravel Cache外观进行添加/获取。
  • MemcachedCache -- 使用PHP本机的Memcached类提供添加/获取。

要执行nonce验证,使用实现CacheInterface接口的对象初始化Server类,例如

$server = new Server(null, new MemcachedCache());

要创建nonce,这是正确的调用

$server->createNonce($ip_address);

$ip_address是客户端的IP地址,例如来自$_SERVER数组或类似。

nonce验证(服务器)

在服务器端,nonce验证需要初始化服务器对象的缓存对象,如下面的nonce创建示例所示

$server = new Server(null, new MemcachedCache());

nonce验证规则如下

  • 客户端nonce必须存在,并且从未被使用过。
  • 服务器nonce可能存在。如果存在,它必须是为客户端的特定IP地址在服务器上创建的。

如果客户端nonce或服务器nonce无效,将抛出NonceException。

nonce验证在verifySignatureverifyHMAC调用期间自动发生。

适用的框架

  • Laravel
  • Yii
  • Zend Framework
  • Symfony

这需要一个相对较新的PHP版本,其中openssl库已编译或作为模块加载。

架构

我并未提供所有API安全功能的可能选项。例如,我无法生成DSA或DH密钥(PHP的openssl扩展尚不支持),默认密钥是2048位的RSA密钥(1024位密钥已被破解)。我没有提供所有可能的签名哈希算法——SHA256是推荐使用的。

另一个例子是在创建签名之前,会自动将客户端随机数添加到每个请求中——这可以防止两个具有相同数据的请求有相同的签名(从而导致拒绝服务攻击)。您可以选择不验证客户端随机数,但如果您这样做,它始终会存在。

这是为了提供最佳实践,而不是完全灵活的安全措施。

之所以这样做的原因是我看到太多API在安全方面存在限制或不足。例如,有一个用户名/密码对,并且将它们作为API数据的一部分以明文形式传递,这不是一个有效的安全解决方案。

需要关注的是实际可行性和最高安全性之间的平衡。理想情况下,应对每个API请求进行公钥加密,然而,进行这种加密所需的时间将开始变得显著。另一个选择是将数据密封(使用共享密钥加密,并在公钥加密的数据包中传递共享密钥),然而,这仍然有缺点,即它会破坏各种框架中期望在将数据传递到其他地方之前解析HTTP POST数据的HTTP处理库。

当然,仍然可以在POST体中加密或密封特别敏感的数据,但这可能是在未来版本中的一个练习。