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

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. 상용 벤더사 - Python 자체로 작성된 것은 전무 - c/c++,

    .so 파일 연동을 위한 가이드 제시 HOW
  2. 방안 1. service 에서 암/복호화 수행 Pros : - DB

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

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

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

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

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

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

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

    - 어느 시점에 암복호화를 하는지 명확 - service, repo 는 순수유지 Cons: - 컬럼별 개별 암복호화 이슈 - Table 이 늘어나면? Handler 증가? 좀 더 좋은 방법이 없을까?
  10. SQLAlchemy CustomTypes TypeDecorator Class - 기존 Type에 기능을 추가하는 사용자

    지정 Type 작성 가능 - Subclassing of SQLAlchemy’s built-in types
  11. TypeDecorator process_bind_param - APP => DB - DBAPI 의 execute()

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

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

    형태 - process_bind_param, process_result_value 사용 권장
  14. 결론 DB암호화는 필수 사항 어디에서 암호화를 할 것인가? - USE

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

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

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