首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenSSL::HMAC.hexdigest PHP等价物不会输出与ruby相同的结果

OpenSSL::HMAC.hexdigest PHP等价物不会输出与ruby相同的结果
EN

Stack Overflow用户
提问于 2020-01-17 17:19:44
回答 1查看 1.2K关注 0票数 0

这是我需要转换为PHP的ruby代码:

代码语言:javascript
运行
复制
print OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), 'hello', Base64.encode64('bonjour'))

产出:

62ac34e5d28563d6a50272d6605d1f8c791e41

这是我的PHP代码:

代码语言:javascript
运行
复制
echo hash_hmac('sha1', base64_encode('bonjour'), 'hello');

产出:

89ebf8bd3d92bf3283a4c5f24072820258367e4

我找不到拥有62ac34...的方法。

我也试过:

代码语言:javascript
运行
复制
echo hash_hmac('sha1', 'bonjour', 'hello'); // 1
echo hash_hmac('sha1', 'hello', 'bonjour'); // 2
echo hash_hmac('sha1', base64_encode('hello'), 'bonjour'); // 3
echo hash_hmac('sha1', 'hello', base64_encode('bonjour')); // 4
echo base64_encode(hash_hmac('sha1', 'hello', 'bonjour', TRUE)); //5

这也是错误的。产出:

代码语言:javascript
运行
复制
bed443484cc49c41c053a11dd15e44d4f79c524f // 1
16923f8d6e9afd345cf947fc963cad73aa12b76c // 2
8e5989976296c76f0462fe33c6bc2dec48bdcb5a // 3
ca237e79f77e6d9739db45fc5d162da3a4036639 // 4
FpI/jW6a/TRc+Uf8ljytc6oSt2w= // 5

我完全绝望了。

编辑

卡斯珀的回答并没有完全回应我的期望。对于像bonjour这样的简单字符串,没有问题。但是,当我放置一些更复杂的字符串,一个json字符串或一个更长的字符串(> 60)时,就会出现问题。

首先,遵循Base64 Ruby模块

Encode64(垃圾桶) 返回Base64 64编码的bin版本。该方法符合RFC 2045的要求。每60个编码字符就会添加行提要。

因此,为了在PHP中具有相同的base64编码数据,我需要每60个编码字符插入\n,也需要在字符串末尾插入\n。为此,PHP提供了斯普利特(函数。

因此,这些命令输出相同的字符串:

代码语言:javascript
运行
复制
chunk_split(base64_encode($json), 60, '\n'); // PHP
Base64.encode64(json) # Ruby

但这并不能解决我的问题

PHP和Ruby之间的结果仍然不同:

PHP:

代码语言:javascript
运行
复制
$json = '{"data":["bonjour"],"id":true,"price":false,"oper":null}';
$base64 = chunk_split(base64_encode($json), 60, '\n');
$hash = hash_hmac('sha1', $base64, 'bonjour');
代码语言:javascript
运行
复制
// Ouput from var_dump()
eyJkYXRhIjpbImJvbmpvdXIiXSwiaWQiOnRydWUsInByaWNlIjpmYWxzZSwi\nb3BlciI6bnVsbH0=\n // $base64
fd044c309bea13396ed8df47b5c606d950222ceb // $hash

现在在Ruby中:

代码语言:javascript
运行
复制
json_body = '{"data":["bonjour"],"id":true,"price":false,"oper":null}'
encoded_body = Base64.encode64(json_body)
hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), 'bonjour', encoded_body)
代码语言:javascript
运行
复制
# Ouput from puts var.inspect
eyJkYXRhIjpbImJvbmpvdXIiXSwiaWQiOnRydWUsInByaWNlIjpmYWxzZSwi\nb3BlciI6bnVsbH0=\n # base64
e168f9efe96e9424e22de765c72018c5a3f3437f # hash

注意,$base64 PHP和base64变量是相同的。

我做错什么了?我不知道Ruby,puts.inspect是调试代码的最佳方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-17 17:53:01

看起来Ruby正在向base64编码的字符串中添加新行,而PHP则不是。

红宝石:

代码语言:javascript
运行
复制
Base64.encode64('bonjour')
=> "Ym9uam91cg==\n"

PHP:

代码语言:javascript
运行
复制
base64_encode('bonjour')
=> "Ym9uam91cg=="

现在我们知道了如何在PHP中修复它:

代码语言:javascript
运行
复制
hash_hmac('sha1', base64_encode('bonjour') . "\n", 'hello');
=> "62ac34e5d28563d6a50272d660805d1f8c791e41"

或者在Ruby中修复它:

代码语言:javascript
运行
复制
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), 
                        'hello', Base64.encode64('bonjour').chomp)
=> "89ebf8bd3d92bf3283aa4c5f24072820258367e4"

第2部分

在PHP中,以及在Ruby中,'\n'"\n"不一样。第一个字符产生两个字符(\n),第二个字符生成换行符。

因此,要修复代码,需要在字符串中使用换行符,而不是slash+n:

代码语言:javascript
运行
复制
$base64 = chunk_split(base64_encode($json), 60, "\n");
                                                ^^^^

您还可以用gsub删除Ruby编码字符串中的换行符,这意味着您不需要在gsub代码中使用任何技巧:

代码语言:javascript
运行
复制
encoded_body = Base64.encode64(json_body).gsub("\n", '')
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59792095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档