我通过以下代码将(secret_key,client_id,path)解码为签名:
require 'rubygems'
require 'base64'
require 'cgi'
require 'hmac-sha1'
@client_id = "asdkasdlda"
@secret = "3fdsdsfxds"
binary_key = Base64.decode64(@secret)
params.update({"client" => @client_id})
path = uri_path + "?" + params.collect{|k,v| "#{k}=#{v}"}.inject{|initial,cur| initial + "&" + cur}
digest = HMAC::SHA1.new(binary_key).update(path).digest
digest = Base64.encode64(digest).gsub(/[+\/]/, {"+" => "-", "/" => "_"}).delete("=")
return "#{path}&sig=#{digest}"
因此,此代码会生成sig
和path
。我们按照以下方式向服务器发送请求:
/api/v1/customers/sign_in.json?user[email]=amit1656789@gmail.com&user[password]=[FILTERED]&client=asdkasdlda&sig=JSdP5xUHhgS8ZbKApBOIlsJKg_Q
现在,在服务器端,我想将此params [“sign”]解码为app_id,secret_key和path表示上述代码的反向过程。但我没有找到任何相反的过程。手段
(app_id, secret, path) => "signature"
"signature" => (app_id, secret, path) /* Here i stuck */
答案 0 :(得分:3)
首先你应该知道:
"签名" => (app_id,secret,path)
这不可能。这不是任何类型的MAC的工作方式。签名不包含数据。签名旨在与一起发送他们签名的消息。
对于安全的HMAC,您应该从不使用您签名的消息发送密码。除了通过反复猜测值可能是什么之外,也无法从签名中找出秘密。
确认签名的常用方法是在服务器上执行相同的过程,使用相同的密码(服务器应该已经拥有)签署相同的消息,并比较签名。你已经让自己变得困难,因为你在发送它们时已经签署了params,然后将签名放在最后。你必须重新构建消息。
首先,您需要使用任何Web服务器库来获取请求URI,包括查询字符串
signed_uri = "/api/v1/customers/sign_in.json?user[email]=amit1656789@gmail.com&user[password]=[FILTERED]&client=asdkasdlda&sig=JSdP5xUHhgS8ZbKApBOIlsJKg_Q"
然后将其拆分为消息及其签名(我将其留给您,但只是正则表达式应该有效):
message = "/api/v1/customers/sign_in.json?user[email]=amit1656789@gmail.com&user[password]=[FILTERED]&client=asdkasdlda"
signature = "JSdP5xUHhgS8ZbKApBOIlsJKg_Q"
要将此签名解码回原始摘要(以便于比较),只需反转您在客户端结束时所做的替换和编码:
client_digest = Base64.decode64(
signature.gsub(/[-_]/, {"-" => "+", "_" => "/"}) )
然后在服务器上(你应该已经拥有@secret的值),计算你期望签名的内容:
@secret = '3fdsdsfxds'
binary_key = Base64.decode64(@secret)
server_digest = HMAC::SHA1.new(binary_key).update( message ).digest
if server_digest == client_digest
puts "The message was signed correctly"
else
puts "ERROR: The message or signature is not correct!"
end