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
800
セキュアなRAILSアプリを目指す Part2: 暗号化編(鍵の管理)
free_world21
May 29, 2019
Tweet
Share
More Decks by free_world21
See All by free_world21
DjangoとRailsを使って趣味として政治資金を透明化するプロダクトを作ってる話
free_world21
0
52
Ruby on Rails on Kubernetesってどうなの?
free_world21
0
11
大事なデータを守りたい!ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介
free_world21
0
15
Ruby on Rails と Django を比較してみる
free_world21
1
220
Shinjuku.rb#95:心の技術書紹介
free_world21
1
240
Rails engineを用いたゆるふわモジュラーモノリス のご紹介
free_world21
1
410
『Railsオワコン』と言われる時代に、なぜブルーモ証券はRailsを選ぶのか
free_world21
3
1.3k
東証障害報告書を読み解く
free_world21
0
230
Ruby/Railsの勉強会のおかげでブルーモ証券起業した
free_world21
2
470
Other Decks in Programming
See All in Programming
コーディングは技術者(エンジニア)の嗜みでして / Learning the System Development Mindset from Rock Lady
mackey0225
2
490
Google I/O recap web編 大分Web祭り2025
kponda
0
2.9k
Go製CLIツールをnpmで配布するには
syumai
2
1.2k
The State of Fluid (2025)
s2b
0
170
Bedrock AgentCore ObservabilityによるAIエージェントの運用
licux
9
690
Dart 参戦!!静的型付き言語界の隠れた実力者
kno3a87
0
200
あのころの iPod を どうにか再生させたい
orumin
2
2.5k
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
130
書き捨てではなく継続開発可能なコードをAIコーディングエージェントで書くために意識していること
shuyakinjo
1
280
[DevinMeetupTokyo2025] コード書かせないDevinの使い方
takumiyoshikawa
2
280
Nuances on Kubernetes - RubyConf Taiwan 2025
envek
0
170
一人でAIプロダクトを作るための工夫 〜技術選定・開発プロセス編〜 / I want AI to work harder
rkaga
12
2.6k
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
890
Side Projects
sachag
455
43k
Music & Morning Musume
bryan
46
6.7k
Rails Girls Zürich Keynote
gr2m
95
14k
The Language of Interfaces
destraynor
159
25k
[RailsConf 2023] Rails as a piece of cake
palkan
56
5.8k
Measuring & Analyzing Core Web Vitals
bluesmoon
8
560
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
The Cost Of JavaScript in 2023
addyosmani
53
8.8k
Building an army of robots
kneath
306
45k
Scaling GitHub
holman
462
140k
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