hmac签名在python和php中不同

I need little help to figure out issue with php hash_hmac. I am converting a existing python script into php that call an api for process data. Python script is working fine.

There is few similar question out there, one of them is HMAC value not consistent in Python and PHP but it dosen't help me. I have tried many way but all time i am getting error your signature doesn't match

Here is my php code

$session_id = xxxxxxxxxxxxxxxxxxxxx;
$accessKey = xxxxxxxxxxxxxxxxxxxxxx;
$url = '/APIENDPOINT?action=mobileAccess&autoJoin=true';
$timestamp = date('r');
$body = '{"expireTime": "20160322T2359", "doorOperations": [{"operation": "guest", "doors": ["103"]}], "endPointID": "enpointID", "format": "rfid48"}';

$params["action"] = "mobileAccess";
$params["override"] = "true";

$canonicalized_query = array();
foreach ($params as $param => $value) {
    $param = str_replace("%7E", "~", rawurlencode($param));
    $value = str_replace("%7E", "~", rawurlencode($value));
    $canonicalized_query[] = $param . "=" . $value;
}
ksort($canonicalized_query);
$canonicalized_query = implode("&", $canonicalized_query);

$string_to_sign = "POST
";
$string_to_sign .= base64_encode(md5($body, true))."
";
$string_to_sign .="application/json;charset=utf-8
";
$string_to_sign .= $timestamp."
";
$string_to_sign .= 'APIEDNPOINT?'.$canonicalized_query;
echo strlen($string_to_sign);
$header=array(
    'Date: '.$timestamp,
    'Content-Type: application/json;charset=utf-8', 
    'Content-MD5: '.base64_encode(md5($body, true)),    
    'Authorization: Basic '.$session_id.':'.base64_encode(hash_hmac('sha1', iconv(mb_detect_encoding($string_to_sign, mb_detect_order(), true), "UTF-8", $string_to_sign), iconv(mb_detect_encoding($accessKey, mb_detect_order(), true), "UTF-8", $accessKey), true))

Here is working python code

url=self._basepath+url
        headers={}

        if body:
            # Encode request body as JSON
            body=json.dumps(body)
            headers['Content-Type']='application/json;charset=utf-8'

            # Compute MD5 digest
            h=hashlib.new('md5')
            h.update(body)
            headers['Content-MD5']=base64.b64encode(h.digest())

        # Format the date correctly, after applying the client/server skew
        headers['Date']=email.Utils.formatdate(time()+self._time_skew)

        if sign and 'id' in self._session:
            # Canonicalize the URL
            (canonicalized_resource,q,query_string)=url.partition('?')
            canonicalized_resource+=q+'&'.join(sorted(query_string.split('&')))

            # Build the string to be signed
            string_to_sign=method+"
"
            if 'Content-MD5' in headers:
                string_to_sign+=headers['Content-MD5']
            string_to_sign+="
"
            if 'Content-Type' in headers:
                string_to_sign+=headers['Content-Type']
            string_to_sign+="
"+headers['Date']+"
"+canonicalized_resource

            # Create the signature
            h=hmac.new(self._session['accessKey'].encode('utf-8'),\
                           string_to_sign.encode('utf-8'),hashlib.sha1)
            headers['Authorization']='Basic %s:%s'\
                %(self._session['id'],base64.b64encode(h.digest()))

call for endpoint in python

ws.send_request("POST","APIENDPOINT",\
                                         {"doorOperations": [{"doors": ["101"],"operation": "guest"}],"expireTime": "20150522T2359","format": "rfid48","endPointID":"endpointid"})

I have checked body content md5 & string_to_sign output is same for both script.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问