자격증명 암호화와 메시지 아카이브

웹 · 앱 개발4분 읽기

메시징 클라이언트의 안전을 이야기할 때 흔히 통신 계층까지만 생각합니다. 하지만 두 가지가 더 남습니다. 로그인 토큰 같은 자격증명을 어디에 어떻게 두느냐, 그리고 받은 대화를 어떻게 잃지 않고 보관하느냐입니다. 카카오톡 프로토콜 연구를 Python 모듈로 떼어 내면서 이 두 축을 다시 설계했습니다. 하나는 자격증명을 평문으로 굴리지 않는 암호화 저장이고 다른 하나는 원본이 잘려 나가도 남는 영구 아카이브입니다. 이 글은 그 두 조각을 재사용 가능한 모듈 관점에서 정리합니다.

토큰을 평문으로 두지 않는다

비공식 클라이언트에서 가장 흔한 실수가 로그인 토큰을 파일에 그대로 저장하는 것입니다. 이 토큰이 새면 계정 접근 권한이 통째로 넘어가기 때문에, 저장 방식이 곧 보안 수준을 결정합니다. 그래서 자격증명은 암호화해서 저장하도록 설계했습니다. 사용자가 정한 마스터 키에서 키 파생 함수를 거쳐 실제 암호화 키를 만들고 그 키로 토큰 파일을 암호화합니다.

핵심은 마스터 키 자체를 파일에 두지 않는다는 점입니다. 마스터 키는 환경에서 주입되고 저장되는 것은 그 키로 암호화된 결과물뿐입니다. 저장 파일이 그대로 유출돼도 마스터 키가 없으면 열 수 없습니다. 값을 다 쓴 뒤 메모리에서 지우는 처리까지 더해 자격증명이 노출될 표면을 최대한 줄였습니다.

파생 키 방식이 주는 유연함

마스터 키에서 암호화 키를 파생하는 방식은 운영에도 이점이 있습니다. 실제 암호화 키를 어딘가에 저장해 두고 관리할 필요 없이, 사용자가 기억하거나 비밀 관리 도구에 넣어 둔 마스터 키 하나만 주입하면 됩니다. 파일 시스템에는 늘 암호화된 상태로만 존재하니, 백업을 뜨거나 다른 기기로 옮길 때도 파일 자체는 안전합니다.

이 구조는 CLI 본체에도 이어집니다. 자격증명 파일에는 소유자만 읽고 쓸 수 있는 권한을 강제하고 권한이 느슨하면 경고를 띄워 바로잡도록 안내합니다. 암호화와 파일 권한, 메모리 정리를 겹쳐 두어 어느 한 겹이 뚫려도 다음 겹이 남게 했습니다.

손실형 원본이라는 문제

두 번째 축은 대화 아카이빙입니다. 앞서 로컬 DB 읽기에서 다뤘듯, 카카오톡의 원본 저장소는 손실형이라 오래된 메시지가 시간이 지나면 잘려 나갈 수 있습니다. 원본만 믿고 있다가는 정작 필요할 때 과거 기록이 사라져 있는 상황을 맞습니다. 그래서 진짜 아카이빙은 원본에 의존하지 않는 별도 저장소를 갖는 데서 시작합니다.

해법은 실시간 수신과 영구 저장을 짝짓는 것입니다. 실시간 감시가 받은 모든 메시지를 받는 즉시 우리 저장소에 적재하면, 원본이 나중에 잘려 나가도 아카이브에는 남습니다. 원본은 지금 있는 것을 보는 창이고 아카이브는 한번 받은 것을 잃지 않는 금고인 셈입니다.

멱등 적재로 안전하게 쌓기

영구 저장에서 까다로운 부분은 중복과 재시작입니다. 실시간 연결은 끊겼다 다시 붙기를 반복하고 그 과정에서 같은 메시지가 두 번 들어올 수 있습니다. 그래서 저장소는 메시지 고유 식별자를 기본 키로 삼고 같은 식별자가 들어오면 덮어쓰는 멱등 방식으로 적재합니다. 같은 메시지가 몇 번 들어와도 저장소에는 한 번만 남습니다.

이 성질 덕분에 감시자가 중간에 죽었다 살아나도 아카이브가 어긋나지 않습니다. 재시작 후 이어받은 구간이 앞과 겹쳐도 중복이 생기지 않으니, 안심하고 오래 돌릴 수 있습니다. 저장소는 동시 쓰기를 가정하지 않고 단일 감시자가 자기 파일에 쓰는 구조로 단순하게 유지했고 스키마가 바뀔 때를 대비해 버전 기반의 점진적 이행도 준비해 뒀습니다.

재사용 가능한 조각으로

이 두 축을 Python 모듈로 떼어 낸 이유는 재사용이었습니다. 자격증명 암호화 저장과 채팅 기록 영구화는 카카오톡 CLI만의 관심사가 아니라, 비슷한 클라이언트를 만들 때마다 반복되는 문제입니다. 그래서 로그인 흐름, 실시간 감시, 암호화 저장, 히스토리 적재를 하나의 임포트 가능한 모듈로 묶어 다른 프로젝트가 필요한 조각만 가져다 쓸 수 있게 했습니다.

정리하면 이 도구의 안전은 통신에서 끝나지 않고 저장까지 이어집니다. 토큰은 마스터 키로 파생한 키로 암호화하고 대화는 손실형 원본을 우회해 멱등 저장소에 영구 보관합니다. 이 아카이브가 받는 실시간 이벤트는 LOCO 프로토콜 리버스 엔지니어링에서, 원본을 직접 보는 로컬 읽기 경로는 로컬 DB 읽기에서 이어집니다. 전체 도구의 안전 우선 설계는 카카오톡 자동화 CLI 오픈소스 사례에 정리돼 있습니다.

자주 묻는 질문

자격증명은 어떻게 안전하게 저장하나요?

토큰을 평문으로 두지 않고 사용자가 정한 마스터 키에서 파생한 키로 암호화해 저장합니다. 마스터 키 자체는 파일에 두지 않고 환경에서 주입하며 저장되는 것은 암호화된 결과물뿐입니다. 파일 권한을 소유자 전용으로 강제하고 다 쓴 값은 메모리에서 지우는 처리까지 겹쳐 노출 표면을 최대한 줄였습니다.

원본이 있는데 왜 별도 아카이브가 필요한가요?

카카오톡의 원본 저장소는 손실형이라 오래된 메시지가 시간이 지나면 잘려 나갈 수 있기 때문입니다. 원본만 믿으면 정작 필요할 때 과거 기록이 사라져 있을 수 있습니다. 실시간으로 받은 메시지를 즉시 별도 저장소에 쌓아 두면, 원본이 나중에 잘려도 아카이브에는 남습니다.

감시자가 재시작해도 아카이브가 어긋나지 않나요?

메시지 고유 식별자를 기본 키로 삼아 멱등 방식으로 적재하기 때문에, 같은 메시지가 여러 번 들어와도 저장소에는 한 번만 남습니다. 연결이 끊겼다 다시 붙으며 겹치는 구간이 생겨도 중복이 발생하지 않아 감시자가 중간에 죽었다 살아나도 아카이브가 어긋나지 않고 안전하게 이어집니다.

#암호화#자격증명#SQLite#아카이빙#Python모듈

업무자동화 구축이 필요하신가요?

무료 상담 신청