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
770
セキュアなRAILSアプリを目指す Part2: 暗号化編(鍵の管理)
free_world21
May 29, 2019
Tweet
Share
More Decks by free_world21
See All by free_world21
DjangoとRailsを使って趣味として政治資金を透明化するプロダクトを作ってる話
free_world21
0
38
Ruby on Rails on Kubernetesってどうなの?
free_world21
0
10
大事なデータを守りたい!ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介
free_world21
0
9
Ruby on Rails と Django を比較してみる
free_world21
1
180
Shinjuku.rb#95:心の技術書紹介
free_world21
1
220
Rails engineを用いたゆるふわモジュラーモノリス のご紹介
free_world21
1
380
『Railsオワコン』と言われる時代に、なぜブルーモ証券はRailsを選ぶのか
free_world21
3
1.2k
東証障害報告書を読み解く
free_world21
0
200
Ruby/Railsの勉強会のおかげでブルーモ証券起業した
free_world21
2
440
Other Decks in Programming
See All in Programming
AI時代のリアーキテクチャ戦略 / Re-architecture Strategy in the AI Era
dachi023
0
180
コードに語らせよう――自己ドキュメント化が内包する楽しさについて / Let the Code Speak
nrslib
5
690
ドメイン駆動設計とXPで支える子どもの未来 / Domain-Driven Design and XP Supporting Children's Future
nrslib
0
350
TVer iOSチームの共通認識の作り方 - Findy Job LT iOSアプリ開発の裏側 開発組織が向き合う課題とこれから
techtver
PRO
0
640
Practical Domain-Driven Design - Workshop at NDC 2025
mufrid
0
120
Language Server と喋ろう – TSKaigi 2025
pizzacat83
2
570
型安全なDrag and Dropの設計を考える
yudppp
5
630
eBPFを用いたAIネットワーク監視システム論文の実装 / eBPF Japan Meetup #4
yuukit
3
440
テスト分析入門/Test Analysis Tutorial
goyoki
9
2.5k
ruby.wasmとWebSocketで遊ぼう!
lnit
0
150
JVM の仕組みを理解して PHP で実装してみよう
m3m0r7
PRO
1
240
医療系ソフトウェアのAI駆動開発
koukimiura
1
170
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.7k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
460
A designer walks into a library…
pauljervisheath
205
24k
Rails Girls Zürich Keynote
gr2m
94
13k
It's Worth the Effort
3n
184
28k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.6k
The Cult of Friendly URLs
andyhume
78
6.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
35
2.7k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
12k
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