求助 Python 的语法转换成 PHP 该 怎么写?

2019-05-22 07:53:50 +08:00
 Steps

python 代码如下:

h = hmac.new(args.acesskey_secret, args.method + "\n"+ args.date + "\n"+ args.uri, sha1)
Signature = base64.b64encode(h.digest())

我在网上找的方法

$h = hash_hmac("sha1", $method . "\n" . $date . "\n" . $uri, $acesskey_secret);
$Signature = base64_encode(md5($h));

还是不错,请问哪里出问题了

3439 次点击
所在节点    程序员
17 条回复
reechangs
2019-05-22 07:56:59 +08:00
我以為你搞出來了一個輪子.....能把 Python 轉換成 PHP........我心想這 tmd 也太牛逼了........
whusnoopy
2019-05-22 08:09:12 +08:00
一步一步看结果,不懂 php,但是感觉第二句最后 h.digest() 和 md5($h) 是不等价的
airdge
2019-05-22 08:28:37 +08:00
import hmac
import hashlib
import base64
string = "1234567890"
key = "1234512345"
h = hmac.new(key.encode(),string.encode(),hashlib.sha1)
Signature =base64.b64encode(h.digest())
print(Signature)

$str = '1234567890';
$key = '1234512345';
$h = hash_hmac("sha1", $str, $key, true);
$Signature = base64_encode(($h));
echo $Signature;
应该是这样吧
Takamine
2019-05-22 08:29:58 +08:00
@reechangs 我也以为是这样。23333
ben1024
2019-05-22 10:03:50 +08:00
```
<?php
$method = 'getData';
$date = '2019-05-22';
$uri = 'https://github.com/ElapseAnnals/LaravelPlus';
$acesskey_secret = 'xxxxxxxxx';

$h = hash_hmac("sha1", $method . "\n" . $date . "\n" . $uri, $acesskey_secret);
$signature = base64_encode(md5($h));
echo $signature; // 输出 NjE1OWFhOWMyN2Q0NzdiYTg5ZmExYmQ0NTUyOWQxMTQ=
```
lwb
2019-05-22 10:25:16 +08:00
3 楼正解
cszchen
2019-05-22 13:43:29 +08:00
多了 md5,人家只加密一次,你来了两次
Steps
2019-05-22 15:00:18 +08:00
@airdge #3 $Signature = base64_encode(($h));

2 个括号是认真的吗?

我貌似生成出来的签名还是不对
@lwb #6 3 楼 貌似不对。。

请注意我的
```
args.method + "\n"+ args.date + "\n"+ args.uri
```

是这样的,基本多了换行符的。

3 楼 2 个代码运行出来的内容是一样的吗?
Steps
2019-05-22 15:07:05 +08:00
@cszchen #7 只是多了 md5 ?

但是生成出来的签名是无法认证的。。
Steps
2019-05-22 15:22:30 +08:00
@airdge #3 b64encode 和 b64decode 一组,用来编码和解码字符串,并且有一个替换符号字符的功能。这个功能是这样的:因为 base64 编码后的字符除 了英文字母和数字外还有三个字符 + / =, 其中=只是为了补全编码后的字符数为 4 的整数,而+和 /在一些情况下需要被替换的,b64encode 和 b64decode 正是提供了这样的功能。

查到这个, 是不是 php 还要进行一下字符过滤什么的
ysc3839
2019-05-22 15:41:11 +08:00
因为 PHP 的 hash_hmac 把结果转换成了 hex string。
base64_encode(hex2bin($h));
先转换回来,再 base64 就可以了。
ysc3839
2019-05-22 15:46:01 +08:00
@ysc3839 更正:看了 PHP 的文档发现 hash_hmac 有个 raw_output 的参数,不需要手动转回来。
https://www.php.net/manual/en/function.hash-hmac.php
Steps
2019-05-22 15:51:10 +08:00
@ysc3839 #11 所以我的代码问题出在哪里了?
ysc3839
2019-05-22 15:52:54 +08:00
@Steps 没有设置 raw_output = TRUE.
Steps
2019-05-22 16:03:55 +08:00
@ysc3839 #14 设置了,貌似没有什么用。不晓得我问题出在哪里了
ysc3839
2019-05-22 16:06:11 +08:00
@Steps 发代码来看看。
airdge
2019-05-22 17:08:58 +08:00
@Steps
import hmac
import hashlib
import base64
string = "测试"+"\n"+"2019-05-21"+"http://www.v2ex.com/";
key = "1234512345"
h = hmac.new(key.encode(),string.encode() ,hashlib.sha1)
Signature =base64.b64encode(h.digest())
print(Signature)

输出:b'tKagsQb99N6lv4gFBDkysbEeFXc='

$str = "测试" . "\n"."2019-05-21" . "http://www.v2ex.com/";
$key = '1234512345';
$h = hash_hmac("sha1", $str, $key, true);
$Signature = base64_encode($h);
echo $Signature;

tKagsQb99N6lv4gFBDkysbEeFXc=

和加不加"\n"又没关系
还有 hash_hmac 第三个参数已经设置为 true 了,不需要在手动 hex2bin

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/566407

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX