Каков наилучший способ обфускации числовых идентификаторов в приложении
Учитывая, что у меня есть сайт, на котором у большинства ресурсов есть числовые идентификаторы (например, user.id question.id и т.д.), но, как и немцы, оглядывающиеся на Вторую мировую войну, я бы не стал их раскрывать наблюдателям, что лучший способ обфускации их?
Я предполагаю, что метод будет включать в себя .to_param, а затем некоторый симметричный алгоритм шифрования, но я не уверен, что самое эффективное шифрование и как оно повлияет на время поиска в БД и т.д.
Любые советы с дороги, с которыми можно столкнуться, будут высоко оценены.
Ответы
Ответ 1
Я обычно использую соленый хэш и храню его в БД в индексированном поле. Это зависит от уровня безопасности, который вы ожидаете, но я использую одну соль для всех.
Этот метод делает создание немного дороже, потому что у вас будут INSERT
и UPDATE
, но ваши поисковые запросы будут довольно быстрыми.
Псевдокод:
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
Я опубликовал плагин Rails, который делает это с именем obfuscate_id. Я не нуждался в этом, чтобы быть в безопасности, но просто для того, чтобы идентификатор в URL-адресе был неочевидным для обычного пользователя. Я также хотел, чтобы он выглядел чище, чем длинный хэш.
Это также имеет то преимущество, что не требуется никаких изменений или изменений в базе данных. Это довольно просто.
Просто добавьте драгоценный камень в свой Gemfile
:
gem 'obfuscate_id'
И добавьте вызов идентификатора obfuscate в вашей модели:
class Post < ActiveRecord::Base
obfuscate_id
end
Это создаст такие URL-адреса:
# 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
Ответ 3
Вот решение. Это та же концепция, что и Wukerplank, но есть пара важных отличий.
1) Нет необходимости вставлять запись, а затем обновлять ее. Просто установите uuid перед вставкой с помощью обратного вызова before_create
. Также обратите внимание, что обратный вызов 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
Ответ 4
Вы можете попробовать использовать этот камень,
https://github.com/wbasmayor/masked_id
он запутывает ваш идентификатор и в то же время дает каждой модели собственный обфусканный код, поэтому все нет. 1 id не будет иметь один и тот же хеш. Кроме того, он не отменяет ничего на стороне рельсов, он просто предоставляет новый метод, поэтому он не испортит ваши рельсы, если вы также расширяете их.
Ответ 5
Столкнувшись с подобной проблемой, я создал драгоценный камень для обработки обфускации идентификаторов Model с помощью Blowfish. Это позволяет создавать приятные 11-символьные обфускации идентификаторов "на лету". Предостережение: идентификатор должен находиться в пределах 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"
Ответ 6
Hashids - отличный кросс-платформенный вариант.