frbit / message-signer
此包已废弃,不再维护。没有建议的替代包。
一个灵活的消息签名和验证框架。包括 Guzzle3 和 Guzzle4 插件。
0.2.1
2014-07-19 22:03 UTC
Requires
- php: >=5.4.0
- phpseclib/phpseclib: *
Requires (Dev)
- guzzle/guzzle: >=3.8
- guzzlehttp/guzzle: >=4.1
- mockery/mockery: *
- phpunit/phpunit: *
- react/http: ~0.4
- symfony/http-foundation: >=2.4
Suggests
- ext-openssl: OpenSSL extension is better tested and provides faster signing and verification than the PHP only solution
This package is not auto-updated.
Last update: 2020-01-18 09:46:42 UTC
README
更新
此项目已废弃。此存储库仍在此处用于文档目的。
消息签名者
一个灵活的消息签名和验证框架。
那么您可以用它做什么?例如:编写一个 HTTP REST API 服务器。使用私钥签名客户端请求。在 API 服务器上使用公钥验证请求。
通过 Composer 安装
php composer.phar require "frbit/message-signer:*"
特性
- OpenSSL、phpseclib 或 HMAC 作为加密提供者。
- Symfony HttpFoundation(包括 Laravel 请求,通过继承)和 Guzzle(3 和 4) 请求对象作为消息来源
- 非常灵活的接口
- 包含 Guzzle3 和 Guzzle4 插件(可能有一天会外包)
- 易于扩展
签名传输格式
验证消息有效性需要三个基本信息
- 密钥:用于识别客户端(发送签名消息的一方)并选择正确的密钥以验证签名。
- 日期:实际上并不是必需的。它允许服务器(接收和验证消息的一方)只接受“最近”的消息——否则攻击者至少可以轻松地重新发送拦截的消息。
- 签名:嗯,用于证明消息的有效性。
这些签名信息可以以各种格式传输。内置三种格式,并且可以轻松添加额外的/自定义格式。
这些格式在 \Frbit\MessageSigner\Message\Handler\*
类中实现。
多个头
默认格式。
在这里,每个信息都存储在专用的消息头(例如 HTTP 请求头)中。
X-Sign: The-signature-content
X-Sign-Key: The-key-name
X-Sign-Date: The-date
当然,头的名称是任意的——只要客户端和服务器都知道这些即可。
$builder = new \Frbit\MessageSigner\Builder(); $builder->setMessageHandler(new \Frbit\MessageSigner\Message\Handler\DefaultHeaderHandler()); $signer = $builder->build();
单个头
在此格式中,所有信息都存储(嵌入)在一个单个的、URL 编码的头中。
X-Sign: sign=The-signature-content&key=The-key-name&date=The-date
再次:头的名称是任意的...
$builder = new \Frbit\MessageSigner\Builder(); $builder->setMessageHandler(new \Frbit\MessageSigner\Message\Handler\EmbeddedHeaderHandler()); $signer = $builder->build();
参数
在某些场景中,将信息存储在消息参数(例如 HTTP 请求查询字符串)中是有意义的。
/foo?sign=The-signature-content&key=The-key-name&date=The-date
如前所述:参数名称(如 sign
、date
、key
)是任意的。
$builder = new \Frbit\MessageSigner\Builder(); $builder->setMessageHandler(new \Frbit\MessageSigner\Message\Handler\ParameterHandler()); $signer = $builder->build();
示例
请查看 examples/
文件夹以获取更多代码示例。
使用 guzzle 发送签名请求
<?php require __DIR__ . '/../vendor/autoload.php'; // key repo is required $keys = new \Frbit\MessageSigner\KeyRepository\ArrayKeyRepository(array( 'default' => array( file_get_contents(__DIR__ . '/keys/key1.pem'), file_get_contents(__DIR__ . '/keys/key1.pub') ), )); // build up signer $builder = new \Frbit\MessageSigner\Builder(); $signer = $builder->setKeys($keys)->build(); // generate guzzle3 and add plugin (see examples for guzzle4) $client = new \Guzzle\Http\Client('http://localhost:1234'); $plugin = new \Frbit\MessageSigner\Guzzle\Plugin($signer); $client->addSubscriber($plugin); // perform the (signed) request $client->post('/foo', array('X-Foo' => 'Bar', 'X-Sign-Key' => 'default'), 'body-content')->send();
这将发送类似以下请求
POST /foo HTTP/1.1
Host: localhost:12345
User-Agent: Guzzle/3.8.1 curl/7.22.0 PHP/5.4.25
X-Sign-Key: default
X-Sign-Date: 2014-03-05T18:55:30+01:00
X-Sign: AemEhtuO47X+XJK+3GHKsWXxjt9cuUuOa1OSQCrXuPtToMEvV0tmPC1dPzhYiz/zw3DlOGy69p34MvKFJRyImWoKxkVD7JVHNf5Vq4N1PsZv/JFsyaKgy8uc9WRLZWgRLxNDR8DPQ8IMU7560HHx2WhpFSrFazpiU23MHF5s+QA=
Content-Length: 12
body-content
对 Symfony HttpFoundation 请求进行签名
<?php require __DIR__ . '/../vendor/autoload.php'; // build up signer params $keys = new \Frbit\MessageSigner\KeyRepository\ArrayKeyRepository(array( 'default' => array( file_get_contents(__DIR__ . '/keys/key1.pem'), file_get_contents(__DIR__ . '/keys/key1.pub') ) )); $crypto = new \Frbit\MessageSigner\Crypto\OpenSslCrypto(); $encoder = new \Frbit\MessageSigner\Encoder\Base64Encoder(); $serializer = new \Frbit\MessageSigner\Serializer\JsonSerializer(); $messageHandler = new \Frbit\MessageSigner\Message\Handler\DefaultHeaderHandler(); // create signer $signer = new \Frbit\MessageSigner\Signer\RequestSigner($messageHandler, $encoder, $serializer, $crypto, $keys); // generate symfony request $request = \Symfony\Component\HttpFoundation\Request::create( 'http://localhost:1234/foo', 'POST', array(), array(), array(), array(), 'the-content' ); // sign request $message = new \Frbit\MessageSigner\Message\SymfonyRequestMessage($request); $signature = $signer->sign('default', $message); // dump request echo "-------------\n$request\n-------------\n\n";
将打印
-------------
POST /foo HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: en-us,en;q=0.5
Content-Type: application/x-www-form-urlencoded
Host: localhost:1234
User-Agent: Symfony/2.X
X-Sign: Vq/5na+sP8EQB6m5S7K/JdS9QaAD1U9lyIPdpIT4+CdboPRVI4OT/nNlt1ipjfGelwaaNd48em21F/zVr8il9IxZMQxzP4a9//Z8xQR1Ecf88Abk94MsAfwok7t6PwyBMqckSbzAUa8QjRQm0d/4su2WQ/4yekCcxRMrYKdguro=
X-Sign-Date: 2014-03-05T18:51:38+01:00
X-Sign-Key: default
the-content
-------------