алгоритм шифрования и дешифрования в Rails - PullRequest
10 голосов
/ 13 декабря 2011

Я бы хотел зашифровать и расшифровать одно значение строки атрибута модели с использованием алгоритма AES .

Мне интересно в Rails , какой самый простой способ получить его?Существует ли какая-либо библиотека AES gem, которую можно использовать напрямую?И как его использовать?

В основном мне нужно руководство по применению AES шифрование / дешифрование в приложении Rails.

------- update -------

Я просто заметил, что существует AES gem .Если я добавлю этот драгоценный камень в свой GemFile, как я смогу использовать его в своем приложении для шифрования и дешифрования?

Ответы [ 5 ]

7 голосов
/ 22 декабря 2011

AFAIK, гем aes оборачивает стандартную библиотеку openssl Ruby, чтобы обеспечить гораздо более упрощенный интерфейс.Он поддерживает только aes-256-cbc, то есть 256-битный AES с цепочкой блоков шифрования.Вы, вероятно, добавили бы методы шифрования / дешифрования в свои модели в Rails.

Базовый порядок операций шифрования будет следующим:

  1. вычисление ключа симметричного шифрования AES, 256 бит
  2. опционально вычисляет вектор инициализации для использования с aes-256-cbc (гем aes может сделать это за вас, так что вы можете пропустить этот шаг)
  3. зашифровать ваше сообщение, дополнительно указав вывод :format (Base64 по умолчанию, в противном случае обычные байтовые строки Ruby) и / или вектор инициализации :iv

Это будет:

key = AES.key
=> "6476b3f5ec6dcaddb637e9c9654aa687"    # key ends up as a 32-char long hex string

iv = AES.iv(:base_64)
=> "PPDRCMsZhumCdEO1Zm05uw=="

enc64 = AES.encrypt("hello, secret world", key, {:iv => iv})
=> "PPDRCMsZhumCdEO1Zm05uw==$b3CCy/1dAMJ2JG5T50igEMGtvo9Ppkla1c9vrKbo+zQ="
# note that the encrypted result is the :iv 
# and Base64-transformed encrypted message
# concatenated with $

Затем вы расшифруете enc64путем передачи всей :iv + $ + зашифрованной строки сообщения, а также 256-битной AES key.

AES.decrypt(enc64, key)
=> "hello, secret world"

Имея некоторый опыт использования стандартной библиотеки openssl вРуби, я могу сказать тебе, что документация на английском языке немногочисленна, в то время как японская документация очень хорошая.В любом случае, использование openssl API в лучшем случае сбивает с толку, так что если вы не возражаете ограничиться aes-256-cbc, тогда этот драгоценный камень aes выглядит очень полезным.

Имейте в виду, у автора есть предостережение относительно скорости.Если вы обнаружите, что вам требуется более быстрое решение, вы должны взглянуть на FastAES.Однако FastAES является расширением C и требует компилятора для вашей целевой платформы.

5 голосов
/ 07 ноября 2015

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

Модуль

require 'openssl'
require 'base64'

module Preventurl
  def self.included(base)
    base.extend self
  end

  def cipher
    OpenSSL::Cipher::Cipher.new('aes-256-cbc')  # ('aes-256-cbc')
  end

  def cipher_key
    'jabcderfghfhfddd!'
  end

  def decrypt(value)
    c = cipher.decrypt
    c.key = Digest::SHA256.digest(cipher_key)
    c.update(Base64.decode64(value.to_s)) + c.final
  end

  def encrypt(value)
    c = cipher.encrypt
    c.key = Digest::SHA256.digest(cipher_key)
    Base64.encode64(c.update(value.to_s) + c.final)
  end
end

в контроллере приложения include MyModule

Теперь с любого контроллера:

encrypt("This is a text")
==> "h0RGuW5m3Wk9AAspik9ZXVysOcy2IeQrhQDn85mdo5I=%0A"

decrypt("h0RGuW5m3Wk9AAspik9ZXVysOcy2IeQrhQDn85mdo5I=%0A")

==> "This is a text"
2 голосов
/ 18 ноября 2016

Я наткнулся на ту же проблему и создал для этого простую модель (рельсы 5):

require 'openssl'
require 'base64'

module EncryptableModelConcern
  extend ActiveSupport::Concern

  included do
    before_save :encrypt_encryptable_attributes
    after_save :decrypt_encryptable_attributes
    after_find :decrypt_encryptable_attributes
  end

  module ClassMethods
    # Sets the model `@encryptable_attributes` class instance variable.
    # Encryptable attributes are encrypted before saving using `before_save` hook and decrypted using `after_save` and `after_find` hooks.
    # Example:
    # ```
    #   class Board < BaseModel
    #     encryptable_attributes :name, :title, :content
    #   end
    # ```
    def encryptable_attributes(*attrs)
      @encryptable_attributes = attrs
    end

  end

  # Returns the model's `@encryptable_attributes` class instance variable.
  #
  def encryptable_attributes
    self.class.instance_variable_get(:@encryptable_attributes) || []
  end


  # Encryptes the model's encryptable attributes before saving using Rails' `before_save` hook.
  #
  # **Note: Be careful in calling this method manually as it can corrupt the data.**
  def encrypt_encryptable_attributes
    encryptable_attributes.each do |k|
      self[k] = encrypt(self[k])
    end
  end

  # Decrypts the model's encryptable attributes using Rails' `after_save` and `after_find` hooks.
  #
  # **Note: Be careful in calling this method manually as it can corrupt the data.**
  def decrypt_encryptable_attributes
    encryptable_attributes.each do |k|
      self[k] = decrypt(self[k])
    end
  end

  private

    def cipher
      OpenSSL::Cipher::Cipher.new('aes-256-cbc')
    end

    def cipher_key
      Rails.configuration.crypto['key'] # <-- your own key generator here
    end

    def encrypt(value)
      c = cipher.encrypt
      c.key = Digest::SHA256.digest(cipher_key)
      c.iv = iv = c.random_iv
      Base64.encode64(iv) + Base64.encode64(c.update(value.to_s) + c.final)
    end

    def decrypt(value)
      c = cipher.decrypt
      c.key = Digest::SHA256.digest(cipher_key)
      c.iv = Base64.decode64 value.slice!(0,25)
      c.update(Base64.decode64(value.to_s)) + c.final
    end

end

Включите его в свою модель, чтобы иметь атрибуты шифрования

class Post < ApplicationRecord
  include EncryptableModelConcern
  encryptable_attributes :title, :content
end

Теперь атрибуты вашей модели будут зашифрованы на before_save и расшифрованы на after_save и after_find перехватах.

2 голосов
/ 13 декабря 2011

https://github.com/shuber/attr_encrypted

http://ezcrypto.rubyforge.org/

attr_encrypted хорошо работает для меня - хотя я также использовал Ezcrypto. Он действует как оболочка для библиотеки OpenSSL.

2 голосов
/ 13 декабря 2011

Вы можете использовать библиотеку OpenSSL. Создайте следующие функции, а затем вы сможете использовать методы шифрования и дешифрования.

def aes(m,k,t)
  (aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc').send(m)).key = Digest::SHA256.digest(k)
  aes.update(t) << aes.final
end

def encrypt(key, text)
  aes(:encrypt, key, text)
end

def decrypt(key, text)
  aes(:decrypt, key, text)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...