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
750
セキュアなRAILSアプリを目指す Part2: 暗号化編(鍵の管理)
free_world21
May 29, 2019
Tweet
Share
More Decks by free_world21
See All by free_world21
DjangoとRailsを使って趣味として政治資金を透明化するプロダクトを作ってる話
free_world21
0
31
Ruby on Rails on Kubernetesってどうなの?
free_world21
0
9
大事なデータを守りたい!ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介
free_world21
0
9
Ruby on Rails と Django を比較してみる
free_world21
1
160
Shinjuku.rb#95:心の技術書紹介
free_world21
1
200
Rails engineを用いたゆるふわモジュラーモノリス のご紹介
free_world21
1
360
『Railsオワコン』と言われる時代に、なぜブルーモ証券はRailsを選ぶのか
free_world21
3
1.1k
東証障害報告書を読み解く
free_world21
0
170
Ruby/Railsの勉強会のおかげでブルーモ証券起業した
free_world21
2
420
Other Decks in Programming
See All in Programming
PHP で学ぶ OAuth 入門
azuki
1
120
PHPのガベージコレクションを深掘りしよう
rinchoku
0
260
ベクトル検索システムの気持ち
monochromegane
31
9.8k
S3静的ホスティング+Next.js静的エクスポート で格安webアプリ構築
iharuoru
0
220
Youtube Lofier - Chrome拡張開発
ninikoko
0
2.4k
PHPで書いたAPIをGoに書き換えてみた 〜パフォーマンス改善の可能性を探る実験レポート〜
koguuum
0
130
技術選定を未来に繋いで活用していく
sakito
3
100
Kamal 2 – Get Out of the Cloud
aleksandrov
1
170
Building Scalable Mobile Projects: Fast Builds, High Reusability and Clear Ownership
cyrilmottier
2
250
Devinのメモリ活用の学びを自社サービスにどう組み込むか?
itarutomy
0
2k
趣味全開のAITuber開発
kokushin
0
190
PHPバージョンアップから始めるOSSコントリビュート / how2oss-contribute
dmnlk
1
970
Featured
See All Featured
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.3k
Writing Fast Ruby
sferik
628
61k
Speed Design
sergeychernyshev
29
880
For a Future-Friendly Web
brad_frost
176
9.7k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Automating Front-end Workflow
addyosmani
1369
200k
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