Slide 1

Slide 1 text

Copyright © 2026 FOLIO Co., Ltd. All Rights Reserved. Prismを使った型安全な暗号化 関数型まつり 2026 / Toshifumi Takahashi @_fhhmm

Slide 2

Slide 2 text

2 自己紹介 • 高橋 俊史 / Toshifumi Takahashi • @_fhhmm • 株式会社FOLIO • 顧客基盤ユニット • toCロボアドサービスのバックエンド開発・保守運用 • 以前はFXシステムやHR系SaaSの開発など

Slide 3

Slide 3 text

3 目次 はじめに Encrypted[T], Encryptable[T] Prismの活用 まとめ

Slide 4

Slide 4 text

4 User (Schema Model)の各フィールドはどのような型にするのが考える User(Entity) name: Name email: Email User(Schema Model) encryptedName: ??? encryptedEmail: ??? users encrypted_name encrypted_email はじめに 氏名やメールアドレスを暗号化してDBに保存するケースについて

Slide 5

Slide 5 text

5 はじめに 暗号化後の型をArray[Byte]としてみる 値を取り違えても正常にコンパイルできてしまう User(Entity) name: Name email: Email User(Schema Model) encryptedName: Array[Byte] encryptedEmail: Array[Byte]

Slide 6

Slide 6 text

6 はじめに 専用の暗号化後の型を考えてみる User(Entity) name: Name email: Email User(Schema Model) encryptedName: EncryptedName encryptedEmail: EncryptedEmail • バリューオブジェクトとセットで暗号化後の型を都度定義しなければならない • 処理の共通化がしづらい

Slide 7

Slide 7 text

7 Encrypyed[T] には、下記の操作が必要 • 暗号化処理: T を暗号化して Encrypted[T] を作れる • 復号処理: Encrypted[T] を復号して T に戻せる Encrypted[T], Encryptable[T] 共通化のためにEncrypted[T]を考える T Encrypted[T]

Slide 8

Slide 8 text

8 暗号アルゴリズムが直接扱うのはName などのValue Objectではなく、String → 暗号化/復号処理は String などに対して行うものとして共通化 Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String

Slide 9

Slide 9 text

9 暗号アルゴリズムが直接扱うのはName などのValue Objectではなく、String → 暗号化/復号処理は String などに対して行うものとして共通化 Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String 暗号アルゴリズム ???

Slide 10

Slide 10 text

10 Encryptable[T] は、下記の操作を担う • T から String への変換: 基本的に必ず成功するものとしてOK • String から T への変換: 失敗する可能性も考慮する必要がある e.g. Name のドメインルールへの抵触 Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String 暗号アルゴリズム Encryptable[T]

Slide 11

Slide 11 text

11 T から String への変換: 基本的に必ず成功するものとしてOK Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String 暗号アルゴリズム Encryptable[T]

Slide 12

Slide 12 text

12 String から T への変換: 失敗する可能性も考慮する必要がある Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String 暗号アルゴリズム Encryptable[T]

Slide 13

Slide 13 text

13 Encryptable[T] は、下記の2つを表現する • T を String に変換できる • i.e. T は暗号化できる • (失敗するかもしれないが、) String から T に変換できる • i.e. (失敗するかもしれないが、) T に復号できる Encrypted[T], Encryptable[T] TとStringの間の変換ルールをEncryptable[T]で表現する Encrypted[T] T String 暗号アルゴリズム Encryptable[T]

Slide 14

Slide 14 text

14 Encrypted[T], Encryptable[T] Encrypted[T]とEncryptable[T]の実装イメージ ここまでの実装イメージ(Scala)※あくまでイメージ

Slide 15

Slide 15 text

15 • B => A (必ず変換できる) は暗号化処理の表現 • A => Option[B] (変換に失敗するかもしれない) は復号処理の表現 として利用できる Prism[A, B] とは、B => A , A => Option[B] の2つから構成される Prismの活用 Prismとは https://gakuzzzz.github.io/slides/refactoring_in_scala/#35 を参考に作成

Slide 16

Slide 16 text

16 Prismの活用 Prismを土台としたEncryptableの実装

Slide 17

Slide 17 text

17 Prismの活用 Encryptedの実装

Slide 18

Slide 18 text

18 Encryptable[T] (Prism)と Encrypted[T] を使うことで、下記を実現することができた • 暗号化後の型安全 • 暗号化/復号の枠組みの共通化 Prismの活用 Nameに対しての暗号化/復号処理の呼び出し

Slide 19

Slide 19 text

19 • 暗号化後の型を Array[Byte] とすると、型安全が失われてしまう • また、各暗号化後の型を用意しても、管理の手間が増えたり、処理の共通化がしづらい • Encrypted[T] とすることで、暗号化後も元の型情報を残すことができ、 暗号化/復号の枠組みを共通化することもできる • Prismを活用した Encryptable[T] を使うことで、暗号化可能であることや、 T の暗号化ルールを表すことができる まとめ