在应用程序中混淆数字ID的最佳方法是什么

时间:2011-07-08 09:37:28

标签: ruby-on-rails

鉴于我有一个网站,其中大部分资源都有数字ID(即user.id question.id等),但就像德国人回顾第二次世界大战一样,我宁愿不向观察者透露这些,是什么混淆它们的最佳方法是什么?

我认为该方法将涉及.to_param,然后是一些对称加密算法,但我不确定什么是最有效的加密,以及它将如何影响数据库等中的查找时间。

非常感谢道路上的任何建议。

6 个答案:

答案 0 :(得分:12)

我发布了一个名为obfuscate_id的Rails插件。我不需要它是安全的,但只是为了让网址中的id对于临时用户来说不明显。我还希望它看起来更干净而不是长哈希。

它还具有无需迁移或数据库更改的优点。这很简单。

只需将gem添加到Gemfile

即可
gem 'obfuscate_id'

在模型中添加调用obfuscate id:

class Post < ActiveRecord::Base
  obfuscate_id
end

这将创建这样的网址:

# post 7000
http://example.com/posts/5270192353
# post 7001
http://example.com/posts/7107163820
# post 7002
http://example.com/posts/3296163828

您也不需要以任何特殊方式查找记录,ActiveRecord find就可以了。

Post.find(params[:id])

此处提供更多信息:

https://github.com/namick/obfuscate_id

答案 1 :(得分:11)

我通常使用盐渍哈希并将其存储在索引字段中的数据库中。这取决于您期望的安全级别,但我使用一种盐。

此方法使创建成本更高,因为您将拥有INSERTUPDATE,但您的查找速度会非常快。

伪代码:

class MyModel << ActiveRecord::Base

  MY_SALT = 'some secret string'

  after_create :generate_hashed_id

  def to_param
    self.hashed_id
  end

  def generate_hashed_id
    self.update_attributes(:hashed_id => Digest::SHA1.hexdigest("--#{MY_SALT}--#{self.id}--"))
  end

end

现在,您可以使用MyModel.find_by_hashed_id(params[:id])查找记录而不会产生任何性能影响。

答案 2 :(得分:7)

这是一个解决方案。它与Wukerplank的答案概念相同,但存在一些重要的差异。

1)无需插入记录然后更新它。只需在插入前使用before_create回调设置uuid即可。另请注意,set_uuid回调是私有的。

2)有一个名为SecureRandom的便捷图书馆。用它!我喜欢使用uuid,但SecureRandom也可以生成其他类型的随机数。

3)要查找记录,请使用User.find_by_uuid!(params[:id])。注意“!”。如果找不到像User.find(params[:id])那样的记录,那么会引发错误。

class User
  before_create :set_uuid

  def to_param
    uuid
  end

private

  def set_uuid
    self.uuid = SecureRandom.uuid
  end

end

答案 3 :(得分:5)

Hashids是一个很好的跨平台选项。

答案 4 :(得分:4)

您可以尝试使用此gem,

https://github.com/wbasmayor/masked_id

它模糊了你的id,同时给每个模型它自己的混淆代码所以没有。 1个id不会有相同的哈希值。此外,它不会覆盖导轨侧的任何东西,它只是提供了新的方法,因此如果您也扩展它们,它不会弄乱你的轨道。

答案 5 :(得分:3)

面对类似的问题,我创建了一个gem来处理使用Blowfish模型ID的混淆。这允许动态创建漂亮的11个字符混淆的id。 警告是,id必须在 99,999,999 之内,例如最大长度为8。

https://github.com/mguymon/obfuscate

要与Rails一起使用,请在config / initializers中使用以下命令创建初始值设定项:

require 'obfuscate/obfuscatable'
Obfuscate.setup do |config|
  config.salt = "A weak salt ..."
end

现在添加到您想成为Obfuscatable的模型:

class Message < ActiveRecord::Base
  obfuscatable # a hash of config overrides can be passed.
end

获取11个字符obfuscated_id,它使用Blowfish单块加密:

message = Message.find(1)
obfuscated = message.obfuscated_id           # "NuwhZTtHnko"
clarified = message.clarify_id( obfuscated ) # "1"

Message.find_by_obfuscated_id( obfuscated )

使用Blowfish字符串加密模糊文本块,允许对更长的文本块进行模糊处理:

obfuscated = message.obfuscate( "if you use your imagination, this is a long block of text" ) # "GoxjVCCuBQgaLvttm7mXNEN9U6A_xxBjM3CYWBrsWs640PVXmkuypo7S8rBHEv_z1jP3hhFqQzlI9L1s2DTQ6FYZwfop-xlA"
clarified = message.clarify( obfuscated ) # "if you use your imagination, this is a long block of text"