Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
セキュアなRAILSアプリを目指す Part2: 暗号化編(鍵の管理)
Search
free_world21
May 29, 2019
Programming
1
780
セキュアなRAILSアプリを目指す Part2: 暗号化編(鍵の管理)
free_world21
May 29, 2019
Tweet
Share
More Decks by free_world21
See All by free_world21
DjangoとRailsを使って趣味として政治資金を透明化するプロダクトを作ってる話
free_world21
0
43
Ruby on Rails on Kubernetesってどうなの?
free_world21
0
10
大事なデータを守りたい!ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介
free_world21
0
11
Ruby on Rails と Django を比較してみる
free_world21
1
190
Shinjuku.rb#95:心の技術書紹介
free_world21
1
230
Rails engineを用いたゆるふわモジュラーモノリス のご紹介
free_world21
1
390
『Railsオワコン』と言われる時代に、なぜブルーモ証券はRailsを選ぶのか
free_world21
3
1.2k
東証障害報告書を読み解く
free_world21
0
210
Ruby/Railsの勉強会のおかげでブルーモ証券起業した
free_world21
2
450
Other Decks in Programming
See All in Programming
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
280
データベースコネクションプール(DBCP)の変遷と理解
fujikawa8
1
270
KotlinConf 2025 現地参加の土産話
n_takehata
0
100
統一感のある Go コードを生成 AI の力で手にいれる
otakakot
0
3k
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
240
Benchmark
sysong
0
210
カクヨムAndroidアプリのリブート
numeroanddev
0
430
Spring gRPC で始める gRPC 入門 / Introduction to gRPC with Spring gRPC
mackey0225
2
510
Elixir で IoT 開発、 Nerves なら簡単にできる!?
pojiro
1
150
生成AIコーディングとの向き合い方、AIと共創するという考え方 / How to deal with generative AI coding and the concept of co-creating with AI
seike460
PRO
1
310
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
300
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
360
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Automating Front-end Workflow
addyosmani
1370
200k
Code Review Best Practice
trishagee
68
18k
Fireside Chat
paigeccino
37
3.5k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
16
940
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.4k
Done Done
chrislema
184
16k
Product Roadmaps are Hard
iamctodd
PRO
53
11k
Stop Working from a Prison Cell
hatefulcrawdad
269
20k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Typedesign – Prime Four
hannesfritz
42
2.7k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Transcript
セキュアなRAILSア プリを⽬指す Part2: 暗号化編(鍵の管理) 2019/05/29 Ebisu.rb
▪ ⼩林 悟史(35) ▪ 本業: 乞⾷(主にポイント、携帯電話) ▪ 副業: プログラマ ▪
2008: フリーランスエンジニアとして独⽴ – flash/C#/rails/iOS/Androidなどなど ▪ 2009: ⼤学院修了(情報理⼯学修⼠) ▪ 2009: IPA未踏事業に採択される ▪ 2016: エメラダ株式会社に三⾓ ▪ 2018: 同社執⾏役員 ▪ 2019: フリーランス&会社員として活動中 @f_world21
エメラダ株式会社 ▪ ⾦融分野で3業種の登録済み – 第⼀種少額電⼦募集取扱業者(⾦融商品取引業者) – 貸⾦業者 – 電⼦決済等代⾏業(2号) ▪
たくさんの法律を守らないといけない・・・ – ⾦融商品取引法 – 貸⾦業法 – 銀⾏法 – 個⼈情報保護法 – 犯罪による収益の移転防⽌に関する法律(犯収法) – 業界団体の規則・規定 ▪ セキュリティまわりにめっちゃ気を使わないといけない・・・
なぜ暗号化をするのか ▪ ⼊⼝対策・内部対策・外部対策のうち、内部対策のうちの1つ ▪ ⼊⼝対策 – ファイアウォール ▪ 内部対策 –
暗号化 – 詳細なログをとる ▪ 外部対策 – 通信できる経路を絞る(特定のサーバへのみデータ送信可能、みたいな)
暗号化をする際に考慮すべきポイント ▪ 検索性能 – 暗号化したデータをDBに⼊れるとSQLによる検索はできない – アプリケーションレイヤでの検索機能を実装する必要がある ▪ 鍵の管理⽅針 –
暗号鍵をどこにおくべきか ▪ 暗号化の単位 – どのような単位で暗号化するか
暗号化されたデータの検索機能の実装例 ▪ ElasticSearchなどの検索モジュールを⽤意し、そこに平⽂のデータを格納する – ElasticSearchはアプリケーションサーバからのみアクセス可能で、経路は 安全という前提 ▪ 検索⽤に各フィールド(⽒名、住所など)のハッシュ値を別テーブルに保存す る –
完全⼀致の検索のみ可能 ▪ 検索時はアプリケーションサーバ内で⼀括複合して、rubyのコード上で検索す る – PersonalInfo.all.eachみたいにするイメージ
鍵の管理⽅針の例 ▪ 環境変数に平⽂の鍵をおく ▪ S3など、アプリケーションサーバの外に平⽂の鍵をおく – 取得経路は安全という前提 ▪ RailsのEncrypted Credentialsを使う
– Credentials.yml.encを複合する鍵をどうするかという問題は健在 ▪ Key Management Serviceをつかう – AWS, GCP, Azureもあった気がする
暗号化の単位の例 ▪ すべてのデータを1つの暗号鍵で取り扱う ▪ ある程度まとまった単位(テーブル単位)ごとに暗号鍵を⽤意する ▪ 1レコードにつき1つの暗号鍵を⽤意する ▪ 単位を細かくすればするほど –
鍵の流出があっても、盗まれる情報を抑えることができるし、鍵の 交換コストも抑えられる – ⼀括複合するには多くのIOや計算⼒が必要なので、効率的なアルゴ リズム(並列化など)が必要
要件や仕様、ビジネス環境に応じて柔軟に ▪ これらの⽅針は情報の重要性に応じて適宜変えるべき – 【情報資産管理規定】などがあればそれに従う ▪ たとえば個⼈情報などは⼀般的には最重要な情報資産 – 1レコードにつき1鍵 –
平分のデータは絶対に持たないマン – あいまい検索は許しませんとビジネスサイドに強く⾔う⼼が必要 ▪ その他のデータはある程度まとまった単位で暗号化する
Railsでの実装例
愚直に実装するとこんなかんじ personal_info = PersonalInfo.new personal_info.encrypted_first_name = encrypt(”悟史”, key) personal_info.encrypted_last_name =
encrypt(“⼩林”, key) personal_info.save! pi = PersonalInfo.find(1) pi.first_name = decrypt(pi.encrypted_first_name, key) pi.last_name = decrypt(pi.encrypted_last_name, key) puts personal_info.first_name # => “悟史” puts personal_info.last_name # => “⼩林”
透過的に扱いたい︕ ▪ attr_encrypted というgemが便利だった ▪ 各modelのattributeを透過的に扱える personal_info.first_name = ”悟史” personal_info.last_name
= “⼩林” personal_info.save! personal_info = PersonalInfo.find(1) puts personal_info.first_name # => “悟史” puts personal_info.last_name # => “⼩林”
AWS KMSについて ▪ Customer Master Key(CMK)を指定して、data key(新しい暗号鍵)を要求す る – A
▪ 以下のものがKMSから返ってくる – A: 平⽂の暗号鍵 – B: 上記の鍵が暗号化されたもの ▪ Aで暗号化して、それは消去。BをDBなどに保存しておく。 ▪ BをKMSに投げつけると復号化して返してくれる(Aを得られる)ので、データ 本体をAで復号化する CMK has_many :data_keys
たとえばこんなメソッドを⽤意する def data_key if self.encrypted_data_key @kms_client.decrypt(ciphertext_blob: self.encrypted_data_key) else resp =
@kms_client.generate_data_key( key_id: Rails.application.config.x.common['kms_cmk_id'], key_spec: 'AES_256', ) self.encrypted_data_key = resp.ciphertext_blob resp.plaintext end end
demo
まとめ ▪ 暗号化は仕様や要件に応じて、⽤法⽤量をまもってただしく使いましょう ▪ AWS KMSを使ってrailsで暗号化されたデータを扱うしくみを紹介しました ▪ 次回・・・ – 暗号化編(検索機能)
– DBロック – Rubyでbinaryパースする話 https://github.com/f-world21/encryption_sample