Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SQLAlchemy CustomTypes

SQLAlchemy CustomTypes

DB Encryption/Decryption using SQLAlchemy Customtypes

B97968bf727069ae776a34f3a201d85d?s=128

AhnSeongHyun

August 24, 2019
Tweet

Transcript

  1. SQLAlchemy CustomTypes 안성현

  2. DB Encryption SQLAlchemy CustomTypes - TypeDecorator - Usage 목차

  3. 안성현 레이니스트 서버 엔지니어 검색, 결제, 핀테크 발표자 소개 @sh84ahn

  4. DB Encryption

  5. 개인정보 보호법 전자금융업 거래법 WHY?

  6. 고유식별정보 사용자 이름, 생년월일, 휴대폰 번호, 여권 번호, 주민등록번호 등등

    TARGET
  7. 금융관련 정보 거래정보, 결제정보 등등 TARGET

  8. AES256 HOW

  9. AES256 SEED HOW

  10. AES256 - pycrypto - pycryptodome : PyCryptodome is a fork

    of PyCrypto HOW
  11. SEED - C/C++, ASP, JAVA, PHP - HOW

  12. 상용 벤더사 - Python 자체로 작성된 것은 전무 - c/c++,

    .so 파일 연동을 위한 가이드 제시 HOW
  13. API PROJECT STRUCTURE PRESENTATION PERSISTENCE API Endpoint Use Case Data

    BUSINESS LOGIC
  14. API PROJECT STRUCTURE PRESENTATION BUSINESS LOGIC PERSISTENCE view.py service.py repo.py

  15. API PROJECT STRUCTURE PRESENTATION BUSINESS LOGIC PERSISTENCE view.py service.py repo.py

    어디서 암복호화를 해야할까?
  16. 간단한 예제 사용자의 정보의 저장/조회하는 간단한 서비스 shorturl.at/QRVW1

  17. 간단한 예제 Presentation Business Logic Persistence Flask 기반의 앱

  18. 간단한 예제 사용자의 정보를저장하는 테이블

  19. 간단한 예제 service : 비지니스 로직 처리

  20. 간단한 예제 repo : ORM 코드 처리

  21. 방안 1. service 에서 암/복호화 수행 비지니스 로직 + 암복호화

  22. 방안 1. service 에서 암/복호화 수행 Pros : - DB

    관련 부분에서 암호화를 신경 쓸 필요가 없다. - ORM insert, update 코드 그대로 수행.
  23. 방안 1. service 에서 암/복호화 수행 Cons: - 비지니스 로직을

    처리하는 부분에서 수행? - 복호화시 번거로움 : - mapper instance 내 컬럼 변수들이 암호화 되어 있음 - 컬럼별 복호화가 불가피 가장 손쉽게 생각할 수 있는 방법
  24. 방안 2. 복호화 부분은 ORM Mapper 내 property 를 활용

  25. 방안 2. 복호화 부분은 ORM Mapper 내 property 를 활용

    Pros : - 컬럼의 반복적인 복호화 부분 제거(방안 1에 대한 보완) - decrypt() 를 service 에서 호출하지 않아도 된다.
  26. 방안 2. 복호화 부분은 ORM Mapper 내 property 를 활용

    Cons : - encrypt() 는 호출하고 있는데? - User instance 자체가 복호화된 값을 들고 있지 않은 상태 - property 호출시 마다, 복호화 수행, 암호화 서버라면 네트워크 비용 증가 데이터를 담는 클래스에는 로직을 담는 것은 지양하자는 의견 encrypt(), decrypt() 를 호출하는 곳이 다른 파일/다른 레이어
  27. 방안 3. repo 에서 수행

  28. 방안 3. repo 에서 수행 Pros : - DB 암호화이기

    때문에 repo 에서 수행하기 적절 - 비지니스 로직 분리 Cons: - insert, update, select 를 사용하는 함수가 많아지면? 비슷한 부분 재작성! - 암호화 해야하는 Table 이 많아지면? 재작성! - 여전히 컬럼별 복호화 이슈
  29. 방안 4. SQLAlchemy 의 ORM event 를 활용 DB 암호화와

    관련된 QUERY - encrypt : insert, update - decrypt : select 이벤트를 잡아서 처리 할 수는 없을까? Insert, update 가 발생할 때 encrypt() 를 수행? Select 가 발생할 때, decrypt() 를 수행?
  30. 방안 4. SQLAlchemy 의 ORM event 를 활용 ORM Event

    - Attribute Event - Mapper Event - Instance Event - Session Event - Query Event 다양한 이벤트 제공
  31. 방안 4. SQLAlchemy 의 ORM event 를 활용 INSERT, UPDATE

    시 암호화
  32. 방안 4. SQLAlchemy 의 ORM event 를 활용 SELECT 시

    복호화
  33. 방안 4. SQLAlchemy 의 ORM event 를 활용 Pros :

    - 어느 시점에 암복호화를 하는지 명확 - service, repo 는 순수유지 Cons: - 컬럼별 개별 암복호화 이슈 - Table 이 늘어나면? Handler 증가? 좀 더 좋은 방법이 없을까?
  34. SQLAlchemy CustomTypes https://docs.sqlalchemy.org/en/13/core/custom_types.html#custom-types

  35. Intro

  36. Getting Started 간단하게 TestField 를 만들어서 테스트

  37. Getting Started Apply TestField

  38. Getting Started > repo.get(user_id) process_result_value : 20190101 process_result_value : 홍길동

    process_result_value : 01012341234
  39. Getting Started > repo.insert(user_name, birthday, phone_number) process_bind_param : 홍길동 process_bind_param

    : 20190101 process_bind_param : 01012341234
  40. SQLAlchemy CustomTypes TypeDecorator Class - 기존 Type에 기능을 추가하는 사용자

    지정 Type 작성 가능 - Subclassing of SQLAlchemy’s built-in types
  41. TypeDecorator class variable required TypeEngine의 참조 어떤 built-in type 의

    subclass 인지 명시
  42. TypeDecorator process_bind_param - APP => DB - DBAPI 의 execute()

    함수로 전달될 값(value) 를 전달 받는다. - value serializing, transformation - 주의 : reverse operation - process_result_value()
  43. TypeDecorator process_result_value - APP < = DB - DB 에서

    데이터를 가져오는 부분(fetch)에 해당 - a result-row column value to be converted - 주의 : reverse operation - process_bind_param()
  44. TypeDecorator bind_processor, result_processor - processor 함수를 정의해서 넘길 수 있는

    형태 - process_bind_param, process_result_value 사용 권장
  45. Usage JSON Encoded

  46. Usage phone_number masking

  47. Usage AmountType https://techspot.zzzeek.org/2011/10/29/value-agnostic-types-part-ii/

  48. TypeDecorator + DB Encrypt/Decrypt 컬럼별 복호화 이슈 제거

  49. TypeDecorator + DB Encrypt/Decrypt 로직 추가 없이 그대로 사용

  50. TypeDecorator + DB Encrypt/Decrypt ORM 그대로 사용

  51. TypeDecorator + DB Encrypt/Decrypt 순수 비지니스 로직

  52. 결론 DB암호화는 필수 사항 어디에서 암호화를 할 것인가? - USE

    CASE? DATA? 고려해야할 사항: - 암복호화 함수를 호출 하는 부분 이슈 - ORM Mapper 컬럼별 복호화 이슈 - 테스트/유지보수
  53. 결론 SQLAlchemy CustomTypes - TypeDecorator : 기존 타입 + 추가기능

    => 사용자 커스텀 타입 - process_bind_param : execute() 로 실행되기전 바인드 되는 값을 조작 - process_result_value : DB 에서 fetch 하는 데이터에 대한 값을 조작
  54. 결론 TypeDecorator + DB 암호화 ORM Mapper 클래스 자체에서 Column

    별 지정 명시적으로 어떤 컬럼이 암복호화 대상인지 누구나 알 수 있다. 유지보수 암복호화를 호출하는 부분이 EncryptedField 에서만 수행 테스트 용이 복잡도 감소 Business Logic 을 처리하는 service 는 순수 Persistence 에 해당하는 repo 는 ORM 관련 코드만 존재
  55. хࢎ೤פ׮.