【问题标题】:Ruby way to generate a HMAC-SHA1 signature for OAuth为 OAuth 生成 HMAC-SHA1 签名的 Ruby 方法
【发布时间】:2011-05-04 08:30:01
【问题描述】:

我正在编写一个小的 ruby​​ 程序来通过 OAuth 使用 Twitter,但还没有找到正确的方法来执行 HMAC-SHA1 签名。到目前为止,我搞砸了

Base64.encode64(OpenSSL::HMAC.hexdigest(digest, key, stuff)).chomp

但这会输出 Twitter 拒绝的东西,而不是有效的签名。我实际上以更糟糕的方式解决了它,请尽量不要打我:

php -r "echo rawurlencode(base64_encode(hash_hmac('sha1', '#{@signature}', '#{llave}', true)));"

最后一个确实有效,我可以到处做我的事情。

我想要一些关于如何在不回到 PHP 的情况下实际执行此操作的提示。在尝试学习一门语言时,我不太喜欢图书馆,所以宝石几乎是不可能的。

谢谢!

【问题讨论】:

  • 只是想知道,为什么不使用标准的 ruby​​-oath 和 twitter gems?
  • @slainer68 我很想通过将大型生产应用程序的一小部分“翻译”成 ruby​​ 来学习这门语言。当我精通 PHP 时,使用 gems 就没有问题了。
  • 在 php 中你正在做一个 url 编码,而你没有在 ruby​​ 中这样做。先试试看效果如何。

标签: ruby cryptography twitter-oauth sha1


【解决方案1】:

以下代码等同于您的 PHP 代码,尽管我选择不将其包装在一行中。

我正在使用 gem ruby​​-hmac,因为它适用于 1.8 和 Ruby 1.9。如果你只使用 Ruby 1.9,我相信标准库包“digest”已经实现了 HMAC(但在 1.8 版本的包中没有这个)。确保gem install ruby-hmac

require 'rubygems'
require 'base64'
require 'cgi'
require 'hmac-sha1'

key = '1234'
signature = 'abcdef'
hmac = HMAC::SHA1.new(key)
hmac.update(signature)
puts CGI.escape(Base64.encode64("#{hmac.digest}\n"))

# equivalent to:
# php -r "echo rawurlencode(base64_encode(hash_hmac('sha1', 'abcdef', '1234', true)));"

更好的是,使用标准库包 OpenSSL(大多数 Linux 和 MacOS 开箱即用)。此代码适用于 Ruby 1.8 和 1.9:

require 'base64'
require 'cgi'
require 'openssl'

key = '1234'
signature = 'abcdef'
puts CGI.escape(Base64.encode64("#{OpenSSL::HMAC.digest('sha1',key, signature)}\n"))

# equivalent to:
# php -r "echo rawurlencode(base64_encode(hash_hmac('sha1', 'abcdef', '1234', true)));"

【讨论】:

  • 另外,如果你想在 PHP 中做与 hash_hmac('sha1', key, signature, false) 相同的事情,那就做 OpenSSL::HMAC.hexdigest('sha1', key, signature)
  • 谨慎使用 Ruby 1.9.3 中的 digest/hmac 库。来自docs:“注意:不鼓励使用这个库,因为这个实现本来是实验性的,但不知何故进入了 1.9 系列而没有引起注意。请在“openssl”库中使用 OpenSSL::HMAC。”
【解决方案2】:
def hmac_sha1(data, secret=HOST_KEY)
    require 'base64'
    require 'cgi'
    require 'openssl'
    hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha1'), secret.encode("ASCII"), data.encode("ASCII"))
    return hmac
end

【讨论】:

  • 如果您也在寻找基于 rails 的解决方案,您可以使用这个人的@ipegasus 答案,然后从该行复制hmac =... 之后的所有内容(无需要求并返回就是我'我说)。而不是 bogart 他的答案也许他也可以编辑。
  • OpenSSL::Digest::Digest 已弃用
  • @akostadinov 推荐什么?
  • 已弃用的OpenSSL::Digest::Digest 的替代方案是使用OpenSSL::Digest: stackoverflow.com/a/24904850/144088
  • 其实我用的是OpenSSL::HMAC.digest,看看github.com/openshift/verification-tests/blob/master/lib/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多