Python和PHP对腾讯云签名hmac_sha256算法实现

Python和PHP对腾讯云签名hmac_sha256算法实现

2023年7月10日发(作者:)

Python和PHP对腾讯云签名hmac_sha256算法实现开宗明义,⽶扑科技在使⽤腾讯云的API接⼝签名中,按照官⽅⽰例开发PHP、Python的接⼝,经常会提⽰签名错误 1

2

3

4

5

6

7

8

9

"Message":

"The provided credentials could not be validated. Please check your signature is correct."

},

"RequestId":

"1ee6ae98-a971-ad9f-4ecc-abcd69ea1234"

}}

"Code":

"ureFailure","Response": {

"Error": {{

本⽂原⽂,请参见⽶扑博客:经过多次尝试探究,发现原因有⼆:1)腾讯云官⽅⽰例不严谨,没有urlencode() 或 () 编码导致提⽰签名错误2)腾讯官⽅只提供了PHP⽰例,没有提供Python⽰例,两者签名函数有⼀些细节

直接给出⼲货,下⾯⽰例是 封装好的腾讯云签名函数,以飨读者。腾讯云签名:阿⾥云签名:⽶扑的官⽹:

PHP 签名⽰例 1

/**

2

* 签名并获取URL结果,json格式返回

3

*

4

* 1. 查询弹性IP列表, DescribeAddresses

5

* 2. 解绑弹性IP, DisassociateAddress

6

* 3. 释放弹性IP, ReleaseAddresses

7

* 4. 公⽹IP转弹性IP, TransformAddress

8

*

9

* @param string $req_action : DescribeAddresses, DisassociateAddress, ReleaseAddresses, TransformAddress

10

* @param string $params : 以 & 开头, 如 &xxx=yyy

11

*/function 12

13

14

15

16

17

18

19

20

qcloud_eip_sign($req_action='DescribeAddresses',

$req_region='ap-beijing',

$req_extra_params='',

$retry_NUM=3) {

global$QCloud_SecretId;

global$QCloud_SecretKey;

21

// $req_action='DescribeAddresses' 22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

$req_signature=

$req_signature_method=

'HmacSHA256';

// HmacSHA1(默认), HmacSHA256$req_secretid=

$QCloud_SecretId;

// 密钥ID,⽤作参数

$req_secretkey=

$QCloud_SecretKey;

// 密钥key,⽤作加密

$req_timestamp=

strtotime(date('YmdHis'));

// 1402992826

$req_nonce= rand(1000, 1000000);

// 随机正整数

$req_version=

'2017-03-12';

$req_api=

'/v2/';// $req_region = 'ap-beijing'; // ap-guangzhou

$req_method=

'GET';

// GET POST'' 44

45

// $req_uri = "/v2/?Action=DescribeAddresses 46

47

// &Region=ap-beijing 48

49

// &Signature=pStJagaKsV2QdkJnBQWYBDByZ9YPBsOi 50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

$req_signature= urlencode(

$req_uri= sprintf("%s%s?%s",

$req_method,

$req_api,

$req_params2);

$req_params2= implode("&",

$req_params_array);sort($req_params_array);

// 以value排序,value值为 Action=DescribeAddresses 、 Region=ap-beijing

$req_params_array=

explode("&",

$req_params);

// &SecretId=AKIDpY8cxBD2GLGK9sT0LaqIczGLFxTsoDF6

// 请求⽅法 + 请求主机 +请求路径 + ? + 请求字符串

$req_params= sprintf("Action=%s&Region=%s&Version=%s&Timestamp=%s&Nonce=%s&SecretId=%s&SignatureMethod=%s%s",

$req_action,

$req_region,

$req_version,

$req_timestamp,

$req_nonce,

$req_secretid,

$req_signature_method,

$req_extra_params);// &Timestamp=1402992826// &Nonce=345122// &Version=2017-03-12// &AddressIds.1=eip-hxlqja90

;

76

77

78

base64_encode(hash_hmac('sha256',

$req_uri,

$req_secretkey, true)));

// urlencode(xxx)

79

80

81

$req_url= sprintf("%s?%s&Signature=%s",

$req_api,

$req_params2,

$req_signature);

$res= curl_url($req_url);

$retry_idx= 0;

while(empty($res) &&

$retry_idx<

$retry_NUM) {

$retry_idx+= 1;

$res= curl_url($req_url);

}

if(!empty($res)) {

$resJson= json_decode($res, true);

$resJson=

$resJson['Response'];

echosprintf("

+++++ action : %s

resJson: ",

$req_action);

print_r($resJson);

return$resJson;

}

else{

returnnull;

}}

$req_action_query=

'DescribeAddresses';

// 查询弹性IP$req_action_unbind=

'DisassociateAddress';

// 解绑弹性IP$req_action_release=

'ReleaseAddresses';

// 释放弹性IP$req_action_transform=

'TransformAddress';

// 公⽹IP转弹性IP

$req_region=

'ap-guangzhou';$req_extra_params=

'';

// 1. 查询弹性IP列表$resJson= qcloud_eip_sign($req_action_query,

$req_region);var_dump($resJson);

运⾏结果: 1

2

3

4

req_url: /v2/?Action=DescribeAddresses&Nonce=585269&Region=ap-guangzhou&SecretId=AKIDSmAAAA2DABCDpTkBBBBMLMFwY0HM1234&SignatureMethod=HmacSHA256&Timestamp=1520429723&Version=201

array (size=3)

5

6

7

8

9

10

11

12

13

'TotalCount'=> int 1

'AddressSet'=>

array (size=1)

0 =>

array (size=11)

'AddressId'=> string

'eip-qy123abc'(length=12)

'AddressName'=> null

14

15

'AddressIp'=> string

'111.230.123.234'(length=15)

16

17

'AddressStatus'=> string

'BIND'(length=4)

18

19

'InstanceId'=> string

'ins-fabc1234'(length=12)

20

'NetworkInterfaceId'=> null

'PrivateAddressIp'=> string

'10.104.245.26'(length=14)

'IsArrears'=> boolean

false

'IsBlocked'=> boolean

false

'IsEipDirectConnection'=> boolean

false

'CreatedTime'=> string

'2018-03-07T12:46:26Z'(length=20)

'RequestId'=> string

'ad28067e-d1f9-4c47-932e-6bba1d123456'(length=36) 代码说明:1)函数抽象封装签名⽅法,⽅便管理维护,减少开发⼯作量2)参数按照升序排列 explode(xxx) —> sort($req_params_array) —> implode(xxx)3)签名⽅法,需要添加 urlencode,否则经常提⽰签名错误,原因是未urlencode会有⼀些 空格、加号(+)、等号(=)等特殊字符$req_signature = urlencode(base64_encode(hash_hmac('sha256', $req_uri, $req_secretkey, true))); // urlencode(xxx)

Python 签名⽰例 1

#!/usr/bin/env python# -*- coding:utf-8 -*- 2

3

# 2018-01-08 4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

rs

importsysreload(sys)aultencoding('utf-8')

## 腾讯云API接⼝签名defqcloud_eip_sign(req_action='DescribeAddresses', req_region='ap-beijing', req_extra_params='', retry_NUM=3):

req_method

='GET'

# GET POST

req_api

='/v2/'

req_version

=importloggingimporthashlib, base64, hmac, randomimporturllib, urllib2importtime, datetime, os, json

## 28

'2017-03-12'

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

req_timestamp

=int(())

# 1520422452

req_nonce

=t(1000,

1000000)

# 随机正整数

req_secretid

=QCLOUD_SecretId

# 密钥ID,⽤作参数

req_secretkey

=QCLOUD_SecretKey

# 密钥key,⽤作加密

req_signature_method

='HmacSHA256'

# HmacSHA1(默认), HmacSHA256

req_signature

=''

# req_uri = "/v2/?Action=DescribeAddresses# &Version=2017-03-12 44

45

# &Timestamp=1402992826 46

47

# &SecretId=AKIDpY8cxBD2GLGK9sT0LaqIczGLFxTsoDF6 48

49

50

51

52

53

54

55

56

57

58

59

req_params

="Action=%s&Region=%s&Version=%s&Timestamp=%s&Nonce=%s&SecretId=%s&SignatureMethod=%s%s"%(req_action, req_region, req_version, req_timestamp, req_nonce, req_secretid, req_signature_method, req_extra_params)

req_params_array

=req_('&')

req_params_array

=sorted(req_params_array)

# 以value排序,value值为 Action=DescribeAddresses 、 Region=ap-beijing

req_params2

=

# 请求⽅法 + 请求主机 +请求路径 + ? + 请求字符串

# &Nonce=345122# &Signature=pStJagaKsV2QdkJnBQWYBDByZ9YPBsOi# &AddressIds.1=eip-hxlqja90# &Region=ap-beijing'&' 60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

req_url

="%s?%s&Signature=%s"%(req_api, req_params2, req_signature)

('qcloud_eip_sign() - req_url: %s'%(req_url))

res

=spider_url(req_url)

retry_idx

=0;

whilenotres

andretry_idx < retry_NUM:

retry_idx

+=1

res

=spider_url(req_url)

ifres :

resJson

=(res)

resJson

=resJson['Response']

print"

+++++ action : %s

resJson: "%(req_action,)

req_uri

="%s%s?%s"%(req_method, req_api, req_params2)

req_signature

=( base64.b64encode((req_secretkey, req_uri, digestmod=256).digest()) )

# (xxx).join(req_params_array);

returnresJson

else:

returnNone;

if__name__

=="__main__":

req_action_query

='DescribeAddresses'

# 查询弹性IP

req_action_unbind

='DisassociateAddress'

# 解绑弹性IP

req_action_release

='ReleaseAddresses'

# 释放弹性IP

req_action_transform

='TransformAddress'

# 公⽹IP转弹性IP

req_region='ap-guangzhou'

req_extra_params

='';

# 1. 查询弹性IP列表

resJson

=qcloud_eip_sign(req_action_query, req_region)

(resJson)

运⾏结果: 1

2

3

req_url: /v2/index/rpIbQ5jPfe9tW3w9Slom4%3D

.php?Action=DescribeAddresses&Nonce=383782&Region=ap-guangzhou&SecretId=AKIDSmAAAA2DABCDpTkBBBBMLMFwY0HM1234&SignatureMethod=HmacSHA256&Timestamp=1520430569&Version=201 4

{ 5

6

"Response": {

7

8

9

10

11

12

13

"TotalCount": 1,

"AddressSet": [

{

"AddressId":

"eip-qy123abc",

"AddressName": null,

14

15

"AddressIp":

"111.230.123.234",

16

17

"AddressStatus":

"BIND",

18

19

"InstanceId":

"ins-fabc1234",

20

21

22

23

"NetworkInterfaceId": null,

"PrivateAddressIp":

"10.104.245.26",

"IsArrears":

false,

"IsBlocked":

false,

"IsEipDirectConnection":

false,

"CreatedTime":

"2018-03-07T12:46:26Z"

}

],

"RequestId":

"c2ab3f7f-9796-4ade-afb1-6bba1d123456"

}}

代码说明:1)Python改写PHP代码,有⼀些细节,如 int(())、t(1000, 1000000)、sorted(req_params_array)等2)参数按照升序排列 ('&') —> sort($req_params_array) —> '&'.join(xxx)3)签名⽅法,需要添加 、base64.b64encode(xxx)、digest() 等,否则经常提⽰签名错误req_signature = ( base64.b64encode((req_secretkey, req_uri, digestmod=256).digest()) ) # (xxx)

Python 代码⾥,特别要注意 hmac 签名 sha256 后获取的是 digest(),⽽不是 hexdigest() 这⾥错了会⼀直提⽰签名错误!总结之PHP和Python的对应关系1) PHP 签名 1

// sha1$hmac_sha1_str 2

3

4

5

=

base64_encode(hash_hmac("sha1",

$data,

$secret_access_key));

// HMAC-SHA1加密$signature 6

7

= urlencode($hmac_sha1_str);

// 编码URL

// sha256$hmac_sha256_str=

base64_encode(hash_hmac("sha256",

$data,

$secret_access_key));

// HMAC-SHA256加密$signature= urlencode($hmac_sha256_str);

// 编码URL

2)Python 签名 1

2

3

importurllib, base54, hashlib, hmac

# sha1hmac_sha1_str

4

5

=base64.b64encode( (secret_access_key, data, digestmod=1).digest() )signature

6

7

8

=(hmac_sha1_str)

# sha256hmac_sha256_str

9

10

11

=base64.b64encode( (secret_access_key, data, digestmod=256).digest() )signature

=(hmac_sha256_str) 12

13

14

# sha256hmac_sha256_str

=base64.b64encode( (secret_access_key, data, digestmod=256).hexdigest() )

# 16进制,错误signature

=(hmac_sha256_str)

发布者:admin,转转请注明出处:http://www.yc00.com/news/1688932303a184932.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信