개요
대부분의 경우 사용자에게 적절한 보안을 제공하는 것이 필수적입니다.
이는 E2EE(End-to-End Encryption) 암호화와 같은 암호화 방법을 사용하여 구현할 수 있습니다.
종단간 암호화는 메시지를 처음부터 끝까지 평문으로 저장하지 않고 암호화하는 안전한 통신 방법입니다.
클라이언트에서 메시지를 전송하는 단계부터 최종적으로 수신자에 전달되는 단계까지 메시지를 암호화하기 때문에 'End to End Encryption(E2EE)'으로 불리기도 합니다.
종단간 암호화 방법은 메시지를 복호화할 수 있는 키를 서버에 저장하지 않고, 수신자 장치에서 저장합니다. 그래서 수신자에게 발송되는 동안 데이터가 제 3자에 의해 읽히거나 조작될 수 없습니다. 데이터를 전달하는 서버조차 데이터를 복호화할 수 없습니다.
E2EE에 대한 자세한 설명
CryptoKit은 애플이 암호화를 위해 제공하는 프레임워크 입니다.
종단간 암호화 채팅
암호화 채팅에 앞서서 암호화에 사용하는 키에 대해 개념부터 짚고 넘어가겠습니다.
키의 역할
- 공개키 / 비공개키
- 공개키-비공개키 쌍은 비대칭 암호화에 사용됩니다.
- 공개키: 다른 사용자와 안전하게 데이터를 교환하기 위해 공개됩니다.
- 비공개키: 공개키로 암호화된 데이터를 해독하는 데 사용되며, 절대 노출되어서는 안 됩니다.
- 대칭키
- 실제 채팅 메시지는 일반적으로 대칭키(AES 등)를 사용해 암호화됩니다. 이는 비대칭 암호화보다 훨씬 빠르기 때문입니다.
- 대칭키는 안전하게 생성된 후, 비대칭 암호화를 통해 상대방에게 전달됩니다.
공개키 저장의 원칙
공개키를 서버에 저장하는 것은 일반적이지만, 다음 조건을 만족해야 합니다.
- 공개키만 저장해야 함
- 공개키는 누구나 접근할 수 있으므로 서버에 저장해도 보안 문제가 되지 않습니다.
- 비공개키는 클라이언트 디바이스에만 저장되고 외부로 절대 유출되지 않아야 합니다.
- 키의 신뢰성 확보
- 서버에 저장된 공개키가 위변조되지 않도록 해야 합니다. 이를 위해 키 인증 또는 인증서를 활용해야 합니다.
- 사용자 공개키를 업로드할 때 디지털 서명을 적용하거나, 공개키에 대해
Key Fingerprint를 사용자 간 확인할 수 있는 기능을 제공하는 것도 방법입니다.
공개키를 서버에서 관리하는 이유
서로의 공개키를 쉽게 검색하고 교환할 수 있도록 하기 위해 서버에 저장하는 것이 일반적입니다.
보안은 언제나 개념이 어려워서 이해하지 못하면 길을 잃을 수 있기 때문에 꼭 이해하고 넘어가면 좋겠습니다.
앞선 개념을 이해했다면 본격적으로 암호화 채팅 프로세스를 알아보겠습니다.
채팅 암호화 흐름
- 초기 키 교환
- 사용자는 자신의 공개키를 서버에 업로드합니다.
- 상대방의 공개키를 서버에서 받아옵니다.
- 대칭키 생성
- 클라이언트는 대칭키(예: AES 키)를 생성합니다.
- 이 대칭키를 상대방의 공개키를 사용하여 암호화합니다.
- 대칭키 전송
- 암호화된 대칭키를 상대방에게 전송합니다.
- 상대방은 자신의 비공개키를 사용해 대칭키를 복호화합니다.
- 채팅 메시지 암호화
- 이후 채팅 메시지는 대칭키를 사용하여 암호화 및 복호화됩니다.
암호화 흐름을 보면 의문이 드는 것이 1 대 1 채팅에서는 송신자와 수신자가 각각 1명이기 때문에 수신자의 공개키로 대칭키를 생성하면 되지만 그룹 채팅에서는 수신자가 여러 명인데 대칭키를 어떻게 생성해야 하는 걸까?라는 생각이 들었습니다.
그래서 그룹 채팅에서는 키 생성과 관리를 어떻게 하는지 아래의 3가지 방식을 통해 알아보겠습니다.
그룹 채팅에서의 키 관리 방식
A. 모든 참여자와 개별적으로 키를 교환 (Naive 방식)
- 구현
- 그룹 참여자 각각의 공개키를 서버에서 다운로드합니다.
- 각 사용자에게 개별적으로 암호화된 메시지를 전송합니다.
- 메시지 암호화는 각 사용자마다 별도의 공개키를 사용하여 수행됩니다.
- 단점
- 사용자가 많아질수록 메시지 암호화/복호화가 비효율적입니다.
- 그룹 동기화 관리가 어렵습니다.
B. 그룹 키를 생성하여 공유
- 그룹 키 생성
- 그룹 생성 시, 방 고유의 그룹 키(대칭키)를 생성합니다.
- 그룹 키는 모든 메시지를 암호화하는 데 사용됩니다.
- 그룹 키 배포
- 그룹 참여자 각각의 공개키를 사용해 그룹 키를 암호화하여 개별적으로 전송합니다.
- 새로운 사용자가 그룹에 추가될 경우, 기존 참여자의 비공개키와 상호작용 없이 새 사용자에게 그룹 키를 전송할 수 있습니다.
- 기존 사용자가 그룹에서 제거되면 새로운 그룹 키를 생성하고 남은 사용자들에게 다시 배포합니다.
- 메시지 암호화/복호화
- 메시지를 그룹 키로 암호화하여 모든 사용자에게 전송합니다.
- 사용자는 자신의 클라이언트에서 그룹 키로 메시지를 복호화합니다.
- 장점
- 메시지 암호화/복호화가 효율적입니다(단일 키로 처리).
- 그룹 키만 변경하면 되므로 동적 사용자 추가/삭제가 간단합니다.
- 단점
- 그룹 키가 유출되면 해당 키로 암호화된 모든 메시지가 노출될 위험이 있습니다.
- 이를 완화하려면 키를 주기적으로 교체하거나 메시지별 키를 사용해야 합니다.
C. Signal 프로토콜 기반: Double Ratchet 알고리즘
Signal 프로토콜은 Double Ratchet 알고리즘을 사용해 보안을 극대화합니다. 그룹 채팅에서 Signal의 "Sender Key" 방식이 자주 사용됩니다.
- 초기 단계 (1:1 키 교환)
- 모든 사용자는 자신의 공개키를 그룹에 공유하여, 모든 사용자와 안전하게 초기 키를 교환합니다.
- Sender Key
- 그룹 채팅에서 각 메시지 발신자는 Sender Key(발신자 키)를 생성합니다.
- Sender Key는 발신자가 생성한 대칭키로, 해당 발신자의 메시지를 암호화하는 데 사용됩니다.
- Sender Key는 발신자의 공개키를 사용해 다른 사용자에게 안전하게 전송됩니다.
- 메시지 암호화
- 메시지는 Sender Key로 암호화됩니다.
- 모든 수신자는 자신의 로컬 키 관리 시스템을 통해 Sender Key를 복호화한 뒤 메시지를 읽습니다.
- 사용자 추가/삭제
- 새로운 사용자가 추가되면 새로운 Sender Key를 생성하여 배포합니다.
- 기존 사용자가 삭제되면 새 그룹 키와 Sender Key를 재생성합니다.
- 장점
- 높은 보안 수준과 전달 보안이 보장됩니다.
- 각 발신자의 키를 독립적으로 관리하므로 유연성이 큽니다.
- 단점
- 구현이 복잡하며, 키 관리에 더 많은 리소스가 필요합니다.
결론
B 방식(그룹 키를 생성하여 공유하는 방식)은 그룹 채팅에서 효율적이면서도 보안을 유지할 수 있는 방법으로, 상대적으로 구현이 간단하면서도 실용적이기 때문에 암호화 채팅을 B 방식을 사용하여 구현해 보도록 하겠습니다.
그룹 키 방식의 핵심
- 그룹 키
- 그룹의 모든 참여자가 공유하는
대칭키입니다. 이 키는 메시지를 암호화/복호화하는 데 사용됩니다.
- 그룹 키는 안전하게 교환 및 업데이트되며, 새로운 메시지마다 동일한 키를 사용합니다.
- 공개키 암호화
- 각 사용자는 자신의 공개키-비공개키 쌍을 가지고 있으며, 그룹 키를 각 사용자의 공개키로 암호화하여 전달합니다.
- 공개키-비공개키 암호화는
그룹 키를 안전하게 전송하는 데 사용됩니다.
- 사용자 추가/삭제
- 새로운 사용자가 추가되면 그룹 키를 업데이트하여 안전성을 유지합니다.
- 기존 사용자가 삭제되면 새로운 그룹 키를 생성하고 남은 사용자들에게만 공유합니다.
⚠️ 주의해야할 점
-
그룹 키(대칭키)는 메시지 암호화와 복호화에 동일하게 사용되므로, 공격자가 그룹 키를 알게 되면 모든 메시지를 복호화 할 수 있기 때문에 ❌ 절대 평문으로 서버에 저장하면 안 됩니다.
그렇기 때문에 대칭 키는 클라이언트 측에서 Keychain으로 관리를 하거나, 서버에서 암호화된 그룹 키를 조회 후 복호화 해서 사용해야 합니다.
-
그룹 키는 각 사용자의 공개키로 암호화하여 서버를 통해 전달해야 합니다. (서버는 암호화된 상태로만 전달)
-
서버는 대칭키를 직접 알 수 없으며, 암호화된 상태로만 중계해야 합니다.
구현 방식: 단계별 설명
1단계: 초기 키 교환
- 사용자 공개키 등록
- 모든 사용자는 자신의 공개키를 서버에 등록합니다.
- 예:
User A의 공개키는 서버에서 User B, User C 등이 다운로드할 수 있도록 저장됩니다.
- 그룹 생성 시 그룹 키 생성
- 그룹 생성 시, 서버 또는 그룹 관리자 클라이언트에서 고유한 대칭키(그룹 키)를 생성합니다.
- 그룹 키는 128비트 또는 256비트 AES 키와 같이 강력한 키 생성 알고리즘을 사용합니다.
- 그룹 키 암호화 및 전송
- 그룹 키는 참여자의 공개키를 사용하여 각각 암호화됩니다.
- 예시)
Group Key를 User A의 공개키로 암호화 → Encrypted_Group_Key_A
Group Key를 User B의 공개키로 암호화 → Encrypted_Group_Key_B
- 암호화된 그룹 키를 각각의 사용자에게 전송합니다.
- 사용자별 키 복호화
- 각 사용자는 자신의 비공개키를 사용하여 암호화된 그룹 키를 복호화합니다.
- 예시)
User A는 자신의 비공개키를 사용해 Encrypted_Group_Key_A를 복호화하여 그룹 키를 얻습니다.
2단계: 메시지 암호화와 복호화
- 메시지 암호화
- 그룹 참여자는 채팅 메시지를 작성할 때, 공유된 그룹 키를 사용해 메시지를 암호화합니다.
- 예시) AES-256-GCM 알고리즘으로 메시지를 암호화.
- 메시지 전송
- 암호화된 메시지는 서버를 통해 전달되지만, 서버는 메시지의 내용을 읽을 수 없습니다. (E2EE 보장)
- 메시지 복호화
- 메시지를 수신한 사용자는 공유된 그룹 키를 사용하여 암호화된 메시지를 복호화합니다.
3단계: 사용자 추가
- 새로운 사용자 공개키 확인
- 새로 추가된 사용자가 자신의 공개키를 서버에 등록합니다.
- 새로운 그룹 키 생성
- 새 사용자가 추가되었으므로, 보안을 위해 새로운 그룹 키를 생성합니다.
- 그룹 키 암호화 및 전송
- 새 그룹 키를 기존 참여자와 새 사용자 모두의 공개키로 암호화하여 전달합니다.
4단계: 사용자 삭제
- 그룹 키 변경
- 기존 사용자가 삭제되면, 이전 그룹 키를 폐기하고 새로운 그룹 키를 생성합니다.
- 키 재배포
- 새로운 그룹 키를 남아 있는 참여자의 공개키로 암호화하여 전달합니다.
- 삭제된 사용자는 새로운 그룹 키를 받지 못하므로 이후 메시지에 접근할 수 없습니다.
구현 방식에서 사용자 추가/삭제 시 새로운 그룹 키를 생성해서 보안을 유지해도 되지만 새로운 그룹 키를 생성하면 기존 메시지는 복호화 할 수 없게 된다는 점이 문제입니다.
따라서 그룹 키를 관리하는 방식에 대해서도 알아보겠습니다.
그룹 키 관리
- 이전 그룹 키 유지 (Backward Compatibility)
새로운 그룹 키를 생성해도 기존 키는 유지하여 과거 메시지 복호화를 가능하게 하는 방법
- 동작
사용자가 추가되거나 삭제될 때, 새 그룹 키를 생성하지만 기존 그룹 키는 유지
과거 메시지는 이전 그룹 키로 복호화할 수 있도록 저장
새로운 메시지는 새 그룹 키로 암호화하여 전송
- 메시지 단위 개별 키 사용 (Double Ratchet & Signal Protocol)
각 메시지마다 새로운 키를 생성하는 방법 (Signal Protocol에서 사용)
-
동작
초기에는 공유된 그룹 키를 사용하여 개별 메시지 키를 생성
각 메시지는 개별 키(derived key) 로 암호화하여 보냄
사용자가 추가되거나 삭제되더라도, 이전 메시지들은 그때그때 생성된 개별 키로 복호화 가능
즉, 메시지마다 다른 키를 사용하므로, 그룹 키 변경이 영향을 주지 않습니다.
해당 방법은 Signal 프로토콜에서 Double Ratchet 방식을 사용해서 실제로 WhatsApp, Telegram 등에서 쓰이고 있다고 합니다.
- 그룹 키 래핑(Group Key Wrapping)
그룹 키 자체를 개별 사용자 키로 암호화하여 관리하는 방법
- 동작
그룹 키 자체를 사용자 개별 키(공개키 암호화)를 사용해 암호화하여 저장
새로운 사용자가 추가되면, 기존 그룹 키를 새 사용자의 공개키로 암호화하여 전달
기존 사용자가 삭제되면, 새 그룹 키를 생성하고 기존 사용자들에게만 배포
마무리
개념과 프로세스가 복잡하지만, 종단간 암호화의 개념, 키 교환 방식과 키 관리 방법을 통해 종단간 암호화(E2EE)를 사용한 채팅 시스템을 구현하는 방법에 대해 알아보았습니다.
구현 방법
암호화 채팅 포스팅 2편
암호화 채팅 구현
참고자료
https://getstream.io/blog/ios-cryptokit-framework-chat/
https://dadahae0320.tistory.com/48
https://phillip5094.tistory.com/21
https://velog.io/@gs0351/대칭키-vs-공개키비대칭키
호오... 대단합니다..!