php 实现http-signature来生成authrization

来源:互联网 发布:修改表的sql语句 编辑:程序博客网 时间:2024/05/16 08:04

最近在做一个使用http-signature进行加密来生成Authorization请求头的功能。上网找了一些类库,到最后发现不好用,于是就自己用PHP实现了。

封装的类库如下:

<?php

class HttpSignature
{
    private $_keyId;
    private $_key;
    private $_algorithm;
    private $_headers;
    private $_options;

    static $algorithmList = [
        'hmac-sha1',
        'hmac-sha256',
        'hmac-sha512',
        'rsa-sha1',
        'rsa-sha256',
        'rsa-sha512',
    ];

    private function __construct($keyId, $algorithm , $headers)
    {
        $this->_keyId = $keyId;
        $this->_algorithm = $algorithm;
        $this->_headers = $headers;
    }

    public static function getInstance(
        $keyId,
        $algorithm = 'rsa-sha256',
        $headers = ['date', 'content-md5']
    ) {
        return new BTCChina_Affiliate_HttpSignature(
            $keyId, $algorithm, $headers
        );
    }

    public function getAuthorization($signHeaders = [])
    {
        $this->_setKey();
        $this->_setOptions();
        $data = $this->_getData($signHeaders);
        $signature = $this->_getSignature($data);

        $authorization = sprintf(
            'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"',
            $this->_options['keyId'],
            $this->_options['algorithm'],
            implode(' ', $this->_options['headers']),
            base64_encode($signature)
        );

        return $authorization;
    }

    private function _setKey()

   {
        $keyPath =  APPLICATION_PATH . '/configs/cert/affiliate_priv.pem';
        $this->_key = file_get_contents($keyPath);
    }

    private function _getData($signHeaders = [])
    {
        if (!is_array($signHeaders) || !$signHeaders) {
            throw new Exception('sign headers is not an array');
        }

        return join("\n", $signHeaders);
    }

    private function _getSignature($data)
    {
        if (!in_array($this->_options['algorithm'], self::$algorithmList)) {
            throw new Exception("unsupported algorithm");
        }

        $alg = explode('-', $this->_options['algorithm'], 2);
        switch ($alg[0]) {
            case 'rsa':
                $map = [
                    'sha1'   => OPENSSL_ALGO_SHA1,
                    'sha256' => OPENSSL_ALGO_SHA256,
                    'sha512' => OPENSSL_ALGO_SHA512
                ];

                $key = openssl_get_privatekey($this->_options['key']);
                if ($key === false) {
                    throw new Exception('key option could not be parsed.');
                }

                if (openssl_sign($data, $signature, $key, $map[$alg[1]]) === false) {
                    throw new Exception('unable to signature');
                }

                openssl_free_key($key);
                break;
            case 'hmac':
                $signature = hash_hmac($alg[1], $data, $this->_options['key'], true);
                break;
            default:
                throw new Exception("unsupported algorithm");
        }

        return $signature;
    }

    private function _setOptions()
    {
        $options = [
            'headers'   => $this->_headers,
            'algorithm' => $this->_algorithm,
            'key'       => $this->_key,
            'keyId'     => $this->_keyId
        ];

        if (!is_array($options) || !options) {
            throw new Exception('options are not an array');
        }

        if (!array_key_exists('keyId', $options)
            || !is_string($options['keyId'])
        ) {
            throw new Exception('keyId option is missing');
        }

        if (!array_key_exists('key', $options)
            || !is_string($options['key'])
        ) {
            throw new Exception('key option is missing');
        }

        if (!array_key_exists('headers', $options)
            || !is_array($options['headers'])
        ) {
            throw new Exception('headers option is missing');
        }

        if (!array_key_exists('algorithm', $options)) {
            throw new Exception('algorithm option is missing');
        }

        if (!in_array($options['algorithm'], self::$algorithmList)) {
            throw new Exception('algorithm option is not unsupported');
        }

        $this->_options = $options;
    }
}


key可以使用openssl来生成rsa的公钥和私钥。


然后可以传需要的参数就可以生成Authorization了。

可以使用PHP的curl类库来去请求接口:

function _curl($url = '', $headers = [], $method = 'GET', $params = [])
{
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);

        if ($headers) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }

        $response = curl_exec($ch);
        $httpInfo = curl_getinfo($ch);
        $error = curl_error($ch);
        curl_close($ch);

        return [$response, $httpInfo['http_code'], $error];

}




0 0
原创粉丝点击