Spec-Zone.ru › Ruby on Rails 7.0

класс ActiveSupport::MessageEncryptor

Родитель:
Объект

MessageEncryptor — простой способ шифрования значений, которые хранятся в недоверенном месте.

Шифртекст и вектор инициализации закодированы в base64 и возвращаются вам.

Это можно использовать в ситуациях, похожих на MessageVerifier, но где вы не хотите, чтобы пользователи могли определить значение полезной нагрузки.

len   = ActiveSupport::MessageEncryptor.key_len
salt  = SecureRandom.random_bytes(len)
key   = ActiveSupport::KeyGenerator.new('password').generate_key(salt, len) # => "\x89\xE0\x156\xAC..."
crypt = ActiveSupport::MessageEncryptor.new(key)                            # => #<ActiveSupport::MessageEncryptor ...>
encrypted_data = crypt.encrypt_and_sign('my secret data')                   # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
crypt.decrypt_and_verify(encrypted_data)                                    # => "my secret data"

Метод decrypt_and_verify вызовет исключение ActiveSupport::MessageEncryptor::InvalidMessage, если предоставленные данные нельзя расшифровать или проверить.

crypt.decrypt_and_verify('not encrypted data') # => ActiveSupport::MessageEncryptor::InvalidMessage

Ограничение сообщений определённой целью

По умолчанию любое сообщение можно использовать во всём приложении. Но их также можно ограничить определённой :purpose.

token = crypt.encrypt_and_sign("this is the chair", purpose: :login)

Затем при проверке необходимо передать ту же цель, чтобы получить данные обратно:

crypt.decrypt_and_verify(token, purpose: :login)    # => "this is the chair"
crypt.decrypt_and_verify(token, purpose: :shipping) # => nil
crypt.decrypt_and_verify(token)                     # => nil

Аналогично, если у сообщения нет цели, оно не будет возвращено при проверке со специфической целью.

token = crypt.encrypt_and_sign("the conversation is lively")
crypt.decrypt_and_verify(token, purpose: :scare_tactics) # => nil
crypt.decrypt_and_verify(token)                          # => "the conversation is lively"

Установка срока действия сообщений

По умолчанию сообщения действуют вечно, и проверка через год всё ещё вернёт исходное значение. Но срок действия сообщений можно установить на определённое время с помощью :expires_in или :expires_at.

crypt.encrypt_and_sign(parcel, expires_in: 1.month)
crypt.encrypt_and_sign(doowad, expires_at: Time.now.end_of_year)

Затем сообщения можно проверить и вернуть до истечения срока действия. После этого проверка вернёт nil.

Ротация ключей

MessageEncryptor также поддерживает ротацию старых конфигураций, используя стек шифровальщиков. Вызовите rotate для создания и добавления шифровальщика, чтобы decrypt_and_verify также попробовал резервный вариант.

По умолчанию все ротированные шифровальщики используют значения основного шифровальщика, если не указано иное.

Вы бы задали новые значения по умолчанию своему шифровальщику:

crypt = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")

Затем постепенно выводите старые значения из употребления, добавляя их в качестве резервных. Любое сообщение, сгенерированное со старыми значениями, будет работать до тех пор, пока ротация не будет удалена.

crypt.rotate old_secret            # Fallback to an old secret instead of @secret.
crypt.rotate cipher: "aes-256-cbc" # Fallback to an old cipher instead of aes-256-gcm.

Хотя, если и секрет, и шифр были изменены одновременно, вышеизложенное следует объединить в:

crypt.rotate old_secret, cipher: "aes-256-cbc"

Константы

OpenSSLCipherError

Публичные методы класса

key_len(cipher = default_cipher) Показать исходный код
# File activesupport/lib/active_support/message_encryptor.rb, line 163
def self.key_len(cipher = default_cipher)
  OpenSSL::Cipher.new(cipher).key_len
end

Принимая шифр, возвращает длину ключа шифра, чтобы помочь сгенерировать ключ нужного размера.

new(secret, sign_secret = nil, cipher: nil, digest: nil, serializer: nil) Показать исходный код
# File activesupport/lib/active_support/message_encryptor.rb, line 141
def initialize(secret, sign_secret = nil, cipher: nil, digest: nil, serializer: nil)
  @secret = secret
  @sign_secret = sign_secret
  @cipher = cipher || self.class.default_cipher
  @digest = digest || "SHA1" unless aead_mode?
  @verifier = resolve_verifier
  @serializer = serializer || Marshal
end

Инициализирует новый MessageEncryptor. secret должен быть не короче размера ключа шифра. Для стандартного шифра 'aes-256-gcm' это 256 бит. Если вы используете секрет, введённый пользователем, вы можете сгенерировать подходящий ключ, используя ActiveSupport::KeyGenerator или аналогичную функцию вывода ключа.

Первый дополнительный параметр используется в качестве ключа подписи для MessageVerifier. Это позволяет вам указать ключи для шифрования и подписи данных.

ActiveSupport::MessageEncryptor.new('secret', 'signature_secret')

Параметры:

  • :cipher - Шифр для использования. Может быть любым шифром, возвращённым OpenSSL::Cipher.ciphers. Значение по умолчанию — 'aes-256-gcm'.

  • :digest - String хэш-функции для использования при подписи. Значение по умолчанию — SHA1. Игнорируется при использовании шифра AEAD, например, 'aes-256-gcm'.

  • :serializer - Object сериализатор для использования. Значение по умолчанию — Marshal.

Публичные методы экземпляра

decrypt_and_verify(data, purpose: nil, **) Показать исходный код
# File activesupport/lib/active_support/message_encryptor.rb, line 158
def decrypt_and_verify(data, purpose: nil, **)
  _decrypt(verifier.verify(data), purpose)
end

Расшифровывает и проверяет сообщение. Нам необходимо проверить сообщение, чтобы избежать атак с подстановкой данных. См.: www.limited-entropy.com/padding-oracle-attacks/.

encrypt_and_sign(value, expires_at: nil, expires_in: nil, purpose: nil) Показать исходный код
# File activesupport/lib/active_support/message_encryptor.rb, line 152
def encrypt_and_sign(value, expires_at: nil, expires_in: nil, purpose: nil)
  verifier.generate(_encrypt(value, expires_at: expires_at, expires_in: expires_in, purpose: purpose))
end

Шифрует и подписывает сообщение. Нам необходимо подписать сообщение, чтобы избежать атак с подстановкой данных. См.: www.limited-entropy.com/padding-oracle-attacks/.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API