HMAC-SHA1算法签名及Authorization头认证

使用PHP进行HMAC-SHA1签名,并通过Authorization头认证Deom

$app_id = 'id';
$host = "test.abc.com";
$port = "80";
$app_Key = "key";
$app_timestamp = time();
$app_nonce = "8FINtYTUsKbSZGfl".time().rand(10,1000);
$uri = "/account/ass/verify.do";


//build string
$arr = array($app_timestamp, $app_nonce, "POST", $uri, $host, $port);
$text = join("
", $arr) . "

";
var_dump($text);
$sig = get_signature($text, $app_Key);
var_dump($sig);

$headers=array();
$headers[] = "Authorization: MAC id="$app_id",ts="$app_timestamp",nonce="$app_nonce",mac="$sig"";
$headers[]="Content-Type: application/json";


$data='{"h":"2D4D9BE245FC4172989BC5FAD7EC8784","n":"97C5237B","t":"1428462620","v":"8F2ACF569FCBFDA9081248486240170B325AFF6D"}';

$result = curlPost('http://t-id.gionee.com'.$uri,  $headers, $data);

/**
 * @使用HMAC-SHA1算法生成oauth_signature签名值
 *
 * @param $key  密钥
 * @param $str  源串
 *
 * @return 签名值
 */

function get_signature($str, $key) {
    $signature = "";
    if (function_exists('hash_hmac')) {
        $signature = base64_encode(hash_hmac("sha1", $str, $key, true));
    } else {
        $blocksize = 64;
        $hashfunc = 'sha1';
        if (strlen($key) > $blocksize) {
            $key = pack('H*', $hashfunc($key));
        }
        $key = str_pad($key, $blocksize, chr(0x00));
        $ipad = str_repeat(chr(0x36), $blocksize);
        $opad = str_repeat(chr(0x5c), $blocksize);
        $hmac = pack(
            'H*', $hashfunc(
                ($key ^ $opad) . pack(
                    'H*', $hashfunc(
                        ($key ^ $ipad) . $str
                    )
                )
            )
        );
        $signature = base64_encode($hmac);
    }
    return $signature;
}

function curlPost($url, $headers = array(), $data = array()) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //设置不验证ssl, 发送https接口请求时需要加此行
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //设置不验证ssl, 发送https接口请求时需要加此行
    if (!empty($data)) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    if (!empty($headers)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        var_dump('set header');
        var_dump($headers);
    }
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

附:java算法示例:

package net.svr.cas.test.demo;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import net.iharder.Base64;

public class sig_demo_app {
    private static final String MAC_NAME = "HmacSHA1";
    private static final String UTF8 = "UTF-8";
    private static final byte[] BYTEARRAY = new byte[0];

    public static void main(String[] args) {    
        String host = "id.test.cn"; 
        String port = "443"; 
        String app_Key = "请填写你的AppKey";
        String app_timestamp = "1369732102";
        String app_nonce = "8FINtYTUsKbSZGfl";
        String uri = "/account/verify.do";

        String sig = macSig(host, port, app_Key, app_timestamp, app_nonce, "POST", uri);
        System.out.println(sig);
    }

    public static String macSig(String host, String port, String macKey, String timestamp, String nonce, String method, String uri) {
        // 1. build mac string
        // 2. hmac-sha1
        // 3. base64-encoded

        StringBuffer buffer = new StringBuffer();
        buffer.append(timestamp).append("
");
        buffer.append(nonce).append("
");
        buffer.append(method.toUpperCase()).append("
");
        buffer.append(uri).append("
");
        buffer.append(host.toLowerCase()).append("
");
        buffer.append(port).append("
");
        buffer.append("
");
        String text = buffer.toString();
        
        System.out.println(text);

        byte[] ciphertext = null;
        try {
            ciphertext = hmacSHA1Encrypt(macKey, text);
        } catch (Throwable e) {
            return null;
        }

        String sigString = Base64.encodeBytes(ciphertext);
        return sigString;
    }

    public static byte[] hmacSHA1Encrypt(String encryptKey, String encryptText) throws InvalidKeyException, NoSuchAlgorithmException {
        Mac mac = Mac.getInstance(MAC_NAME);
        mac.init(new SecretKeySpec(getBytes(encryptKey), MAC_NAME));
        return mac.doFinal(getBytes(encryptText));
    }
    
    public static byte[] getBytes(String value) {
        return getBytes(value, UTF8);
    }

    public static byte[] getBytes(String value, String charset) {
        if (isNullOrEmpty(value))
            return BYTEARRAY;
        if (isNullOrEmpty(charset))
            charset = UTF8;
        try {
            return value.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            return BYTEARRAY;
        }
    }
    
    public static boolean isNullOrEmpty(String s) {
        if (s == null || s.isEmpty() || s.trim().isEmpty())
            return true;
        return false;
    }
}
原文地址:https://www.cnblogs.com/dannywang/p/4402179.html