Rails로 투명하게 열 암호화

8196 단어 RailsActiveRecord
개인정보를 취급하는 서비스를 생각하면, 아무래도 특정의 컬럼을 암호화할 필요가 나올 수 있다.
몇 가지 젬을 시험해 보았고, 아무것도 확고하지 않았기 때문에 젬을 만들기로 결정했습니다.

기존 gem의 소개와 새로운 암호화 gem의 비교를 해보자 👀

attr_encrypted



ActiveRecord + 암호화로 조사하면 가장 먼저 나오는 gem 중 하나
정의를 하는 쪽은 심플하지만, 사용할 때 좀처럼 버릇이 있다.

암호화하고 싶은 컬럼에 대해서, 2개의 컬럼이 필요하게 되는 것 같다.
class Model < ActiveRecord::Base
  attr_encrypted :field_name, key: ENV["KEY"]
end

# migrationは下記のような定義になる
create_table(:models) do |t|
  t.string(:encrypted_field_name)
  t.string(:encrypted_field_name_iv)
end

암호화 자체는 매우 간단하게 처리 할 수 ​​있습니다.
그러나 #changes 의 값을 알기 힘들거나 field_was 에서 과거 값을 얻을 수 없는 등의 문제가 있다.

특정한 경우에 이상한 거동을 하므로 솔직히 말하면 실용을 견디지 못한다.
instance = Model.create(field: 'hello')
=> <Model id: 1, encrypted_field: "d9thb/Pvj6gMm2TPLHoola3aHsWy\n", encrypted_field_iv: "UfosEdeGJJmIBUHs\n">

instance.field   
=> "hello"

# changes や _was など
instance.field = "hello world"

instance.changes_to_save
=> {"encrypted_field"=>["d9thb/Pvj6gMm2TPLHoola3aHsWy\n", "RxJTGKPG3PMi1NA0LY/tSu9r16sMWfalAFRc\n"],
 "encrypted_field_iv"=>["UfosEdeGJJmIBUHs\n", "1lMAgBaLBrqQUPUU\n"],
 "field"=>[nil, nil]}

instance.field_changed? #=> true
instance.field_was      #=> nil

crypt_keeper



투명 암호화를 구하는 암호화 gem이다.serialize 의 기능을 활용하여 내부 구현은 매우 간단합니다.
class MyModel < ApplicationRecord
  crypt_keeper :field, encryptor: :active_support, key: ENV['KEY'], salt: ENV['SALT']
end

create_table(:models) do |t|
  t.binary(:field)
end

그리고 투명한 암호화를 구분하고 있을 뿐 거동도 간단!!#changes 등의 거동도 정확하고 문제가 없는 것 같다.

암호 형식의 확장도 유연하게 할 수 있기 때문에, 통상 사용하는 분에는 충분히 실용에 견딜 수 있다고 느꼈다.
instance = Model.new(field: 'hello')
instance.save
instance         #=> <Model id: 1, field: "hello">

instance.field   #=> "hello"

instance.field = 'hello world'

instance.changes
# => {"field"=>["hello world", "hello new world"]}

active_record_encryption



이번에 만든 새로운 암호화 gem이다.
이 gem의 특징은 Attribute API를 사용하고 있어, 좋아하는 형태를 취급할 수 있게 된 점이다.
다른 gem은 string형 밖에 다룰 수 없다.

다음과 같이 두 번째 인수에서 원하는 유형을 지정할 수 있습니다.
또, default: 인수로 디폴트치를 설정하는 것도 준비이다! !
class Model < ApplicationRecord
  encrypted_attribute :field, :date 
  encrypted_attribute :field_2, Money.new
  encrypted_attribute :field_3, :string, default: 'default value'
end

실제로 사용해 보면 알지만, 대체로 다른 거동에 대해서는 crypt_keeper와 동등하게 투명하다.serialize 등도 사용할 수 있는 만큼, crypt_keeper 보다 투명할지도 모른다.
instance = Model.new(field: '2000/01/01', field_2: 100)
instance.field_1 #=> Sat, 01 Jan 2000
instance.field_2 #=> <Money value: 100>
instance.field_3 #=> 'default value'

요약


attr_encrypted 는 너무 사용하기 어렵기 때문에, 어떤 경우에서도 선택사항으로부터 벗어날 것 같다.
안녕

String형만 암호화하는 경우는 crypt_keeper 를 사용할 것이다.
그리고 다양한 유형의 데이터를 암호화하려는 경우 active_record_encryption를 사용하는 것이 좋습니다.

좋은 웹페이지 즐겨찾기