$30 off During Our Annual Pro Sale. View Details »

SQLAlchemy CustomTypes

SQLAlchemy CustomTypes

DB Encryption/Decryption using SQLAlchemy Customtypes

AhnSeongHyun

August 24, 2019
Tweet

More Decks by AhnSeongHyun

Other Decks in Programming

Transcript

  1. SQLAlchemy CustomTypes
    안성현

    View Slide

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

    View Slide

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

    View Slide

  4. DB Encryption

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. AES256
    HOW

    View Slide

  9. AES256
    SEED
    HOW

    View Slide

  10. AES256
    - pycrypto
    - pycryptodome
    : PyCryptodome is a fork of PyCrypto
    HOW

    View Slide

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

    View Slide

  12. 상용 벤더사
    - Python 자체로 작성된 것은 전무
    - c/c++, .so 파일 연동을 위한 가이드 제시
    HOW

    View Slide

  13. API PROJECT STRUCTURE
    PRESENTATION
    PERSISTENCE
    API Endpoint
    Use Case
    Data
    BUSINESS LOGIC

    View Slide

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

    View Slide

  15. API PROJECT STRUCTURE
    PRESENTATION
    BUSINESS LOGIC
    PERSISTENCE
    view.py
    service.py
    repo.py
    어디서
    암복호화를
    해야할까?

    View Slide

  16. 간단한 예제
    사용자의 정보의
    저장/조회하는
    간단한 서비스
    shorturl.at/QRVW1

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. 방안 1. service 에서 암/복호화 수행
    Pros :
    - DB 관련 부분에서 암호화를 신경 쓸 필요가 없다.
    - ORM insert, update 코드 그대로 수행.

    View Slide

  23. 방안 1. service 에서 암/복호화 수행
    Cons:
    - 비지니스 로직을 처리하는 부분에서 수행?
    - 복호화시 번거로움 :
    - mapper instance 내 컬럼 변수들이 암호화 되어 있음
    - 컬럼별 복호화가 불가피
    가장 손쉽게 생각할 수 있는 방법

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  27. 방안 3. repo 에서 수행

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. 방안 4. SQLAlchemy 의 ORM event 를 활용
    INSERT, UPDATE 시 암호화

    View Slide

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

    View Slide

  33. 방안 4. SQLAlchemy 의 ORM event 를 활용
    Pros :
    - 어느 시점에 암복호화를 하는지 명확
    - service, repo 는 순수유지
    Cons:
    - 컬럼별 개별 암복호화 이슈
    - Table 이 늘어나면? Handler 증가?
    좀 더 좋은 방법이 없을까?

    View Slide

  34. SQLAlchemy CustomTypes
    https://docs.sqlalchemy.org/en/13/core/custom_types.html#custom-types

    View Slide

  35. Intro

    View Slide

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

    View Slide

  37. Getting Started
    Apply TestField

    View Slide

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

    View Slide

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

    View Slide

  40. SQLAlchemy CustomTypes
    TypeDecorator Class
    - 기존 Type에 기능을 추가하는 사용자 지정 Type 작성 가능
    - Subclassing of SQLAlchemy’s built-in types

    View Slide

  41. TypeDecorator
    class variable
    required
    TypeEngine의 참조
    어떤 built-in type 의
    subclass 인지 명시

    View Slide

  42. TypeDecorator
    process_bind_param
    - APP => DB
    - DBAPI 의 execute() 함수로 전달될 값(value) 를 전달 받는다.
    - value serializing, transformation
    - 주의 : reverse operation - process_result_value()

    View Slide

  43. TypeDecorator
    process_result_value
    - APP < = DB
    - DB 에서 데이터를 가져오는 부분(fetch)에 해당
    - a result-row column value to be converted
    - 주의 : reverse operation - process_bind_param()

    View Slide

  44. TypeDecorator
    bind_processor, result_processor
    - processor 함수를 정의해서 넘길 수 있는 형태
    - process_bind_param, process_result_value 사용 권장

    View Slide

  45. Usage
    JSON Encoded

    View Slide

  46. Usage
    phone_number masking

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  52. 결론
    DB암호화는 필수 사항
    어디에서 암호화를 할 것인가?
    - USE CASE? DATA?
    고려해야할 사항:
    - 암복호화 함수를 호출 하는 부분 이슈
    - ORM Mapper 컬럼별 복호화 이슈
    - 테스트/유지보수

    View Slide

  53. 결론
    SQLAlchemy CustomTypes
    - TypeDecorator : 기존 타입 + 추가기능 => 사용자 커스텀 타입
    - process_bind_param : execute() 로 실행되기전 바인드 되는 값을 조작
    - process_result_value : DB 에서 fetch 하는 데이터에 대한 값을 조작

    View Slide

  54. 결론
    TypeDecorator + DB 암호화
    ORM Mapper 클래스 자체에서 Column 별 지정
    명시적으로 어떤 컬럼이 암복호화 대상인지 누구나 알 수 있다.
    유지보수
    암복호화를 호출하는 부분이 EncryptedField 에서만 수행
    테스트 용이
    복잡도 감소
    Business Logic 을 처리하는 service 는 순수
    Persistence 에 해당하는 repo 는 ORM 관련 코드만 존재

    View Slide

  55. хࢎ೤פ׮.

    View Slide