처음에는 phone DB 서치하여 비교하는 과정이 필요없을 줄 알고 Trait 에 getter 와 setter 를 통해 암/복호화를 구현하고 Model 에서 데이터 set / get 시에 암/복호화가 가능하도록 처리하였다. 근데 API response로 반환해야할 로직 중 DB에서 레코드를 서치하여 비교하는 로직이 있어 데이터를 복호화 과정이 불가피하다. 비밀번호 Hashing 처럼 비교하여 인증 처리하는 것이 아닌 복호화해서 앱 사이드로 전달하는 것도 필요하기때문에 Hash 사용도 불가하다.
- 배경
- DB 유저 테이블 내 개인정보 (이메일 / 전화번호 등) 암호화 필요 (GDPR 기준)
- 암호화된 필드들은 검색이 가능해야 하며 복호화가 가능해야함
- 양방향 암호 알고리즘 필요
- GDPR 기준 민감한 정보 암호화 필요
Crypt 파사드
laravel 의 Crypt 파사드는 기본적으로 AES-256 암호화 알고리즘을 채택하고 있고, 변경도 가능하다. (단, DES 는 보안적 결함으로 사용불가)
처음에는 이 laravel 에서 제공하는 파사드 Crypt 를 이용해보았으나, 이는 프로바이더 단에서 initial vertor를 무작위로 생성하기 때문에 복호화는 가능하지만 DB 테이블 서치가 불가능하다. (왜냐면… 항상 같은 문자열에 대해 다른 암호문을 반환하기 때문..)
뭐 물론 가능은 하다. DB user 테이블에 모든 레코드를 복호화한 뒤 하나하나 비교하면 된다. 퍼포먼스는 아주 안 좋겠지만 말이다.
다른 방법으로는 initial vector를 직접 랜덤으로 생성한 후 User 테이블에 같이 삽입해두는 경우가 있겠다. 그 $iv 를 가져와서 비밀키와 함께 복호화에 사용하면 된다.
Hash
일반적으로 비밀번호에 Hash 를 많이 사용하는데, 단방향성이라 복호화는 불가능하다. 나의 케이스에서는 들어온 파라미터와 복호화된 DB 레코드를 비교를 해야하므로 사용에 부적절하다.
사실 계속 진행하면서 느낀 건, 애초에 이렇게 DB 검색이 가능하고 복호화가 가능하게끔 처리하는건 암호화할 이유가 전혀 없는 것 같다..
GDPR 기준은 개인을 특정할 수 있는 데이터는 암호화되어 보관 / 전송 되어야한다 라는 건데, 이게 참 모호하다… 조금 더 서치해봐야할 듯