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("\n", $arr) . "\n\n"; 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("\n"); buffer.append(nonce).append("\n"); buffer.append(method.toUpperCase()).append("\n"); buffer.append(uri).append("\n"); buffer.append(host.toLowerCase()).append("\n"); buffer.append(port).append("\n"); buffer.append("\n"); 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; } }
每一天都是崭新的