XChaCha20 청크 암호화와 AAD로 위치를 묶는 법

웹 · 앱 개발4분 읽기

영상 하나를 통째로 암호화하면 재생할 때 전체를 받아야만 열 수 있습니다. 스트리밍하려면 파일을 청크로 잘라 각각을 독립적으로 암호화해야 하는데, 이때 새로운 위험이 생깁니다. 청크가 독립적이라는 말은 공격자가 청크를 서로 바꿔치기하거나 순서를 뒤섞어도 각 청크만 보면 여전히 유효한 암호문이라는 뜻이기 때문입니다. Ciphek은 이 문제를 AAD 바인딩으로 풀었습니다.

인증 암호와 AAD

Ciphek이 미디어 청크에 쓰는 것은 XChaCha20-Poly1305입니다. 이것은 스트림 암호 XChaCha20으로 기밀성을 주고 Poly1305 인증 태그로 무결성을 함께 보장하는 인증 암호(AEAD)입니다. AEAD의 핵심은 암호문이 변조되면 복호화가 조용히 잘못된 평문을 내놓는 것이 아니라 인증 태그 검증에서 실패한다는 점입니다. 한 비트만 바뀌어도 복호화가 거부됩니다.

AEAD에는 기밀로 감출 필요는 없지만 무결성은 지켜야 하는 데이터를 함께 묶는 AAD(부가 인증 데이터)라는 입구가 있습니다. AAD는 암호문에 포함되지 않지만 인증 태그 계산에는 들어갑니다. 즉 AAD가 조금이라도 달라지면 같은 키와 논스라도 태그가 어긋나 복호화가 실패합니다. 이 성질을 청크의 위치를 고정하는 데 활용할 수 있습니다.

청크 위치를 41바이트로 인코딩하기

Ciphek은 각 청크의 AAD에 세 가지를 담습니다. 파일 식별자, 청크 인덱스, 이 청크가 마지막인지 여부입니다. 파일 식별자는 36바이트 문자열, 청크 인덱스는 4바이트 빅엔디언 정수, 마지막 청크 여부는 1바이트로 인코딩되어 정확히 41바이트가 됩니다. 이 인코딩은 서로 다른 입력이 절대 같은 바이트열을 만들지 않는 단사 구조라, 위치가 다르면 AAD도 반드시 다릅니다.

이렇게 하면 공격자가 3번 청크를 5번 자리에 끼워 넣어도 복호화 측이 기대하는 AAD는 5번 위치의 값이므로 인증 태그가 맞지 않아 즉시 걸립니다. 다른 파일의 청크를 가져와 섞는 것도, 청크의 순서를 뒤집는 것도 같은 이유로 탐지됩니다. 각 청크가 자기가 어느 파일의 몇 번째 조각인지를 암호학적으로 증명하게 되는 셈입니다. 인덱스만 평문 파일명에 적어 두는 방식과 달리, 위치가 암호문의 무결성에 직접 묶입니다.

24바이트 논스를 쓰는 이유

청크마다 새 논스가 필요합니다. 같은 키에 같은 논스를 두 번 쓰면 스트림 암호의 안전성이 무너지기 때문입니다. 문제는 논스를 어떻게 고를 것인가입니다. 카운터처럼 순차 논스를 관리하면 상태를 어긋나지 않게 유지해야 하는 부담이 있는데, XChaCha20의 24바이트 논스는 이 부담을 덜어 줍니다. 논스 공간이 충분히 넓어서 청크마다 무작위로 뽑아도 충돌 확률이 사실상 0에 수렴하기 때문입니다.

여기서 AES-GCM과 갈립니다. AES-GCM의 논스는 96비트라 무작위로 대량 생성하면 충돌 위험을 진지하게 계산해야 하고 그래서 보통 카운터 기반의 세심한 논스 관리를 요구합니다. 파일이 수천 개의 청크로 나뉘고 사용자마다 파일이 쌓이는 미디어 클라우드에서는 무작위 논스를 마음 편히 쓸 수 있는 넓은 논스 공간이 실질적인 이점입니다. 각 청크는 24바이트 무작위 논스와 함께 저장되고 저장 포맷은 논스와 암호문을 이어 붙인 단순한 구조입니다.

저장과 재생으로 이어지는 계약

이 청크 포맷은 한 번 정하면 바꾸기 어려운 계약입니다. 이미 암호화되어 저장된 모든 파일이 이 포맷을 따르고 있어서 인코딩 규칙을 바꾸면 기존 파일을 열 수 없게 됩니다. 그래서 파일 식별자 길이, 인덱스 바이트 순서, 논스 위치 같은 세부를 초기에 확정하고 문서에 불변 계약으로 못 박았습니다. 청크 하나의 바이트 배치가 곧 시스템 전체의 하위 호환성을 결정합니다.

청크 암호화는 단순히 조각마다 암호를 거는 일이 아니라, 각 조각에 자기 정체성을 새겨 넣어 재조립을 위조할 수 없게 만드는 일입니다. XChaCha20-Poly1305의 넓은 논스와 AAD 입구가 이 목표에 맞았고 41바이트 위치 인코딩이 청크를 제자리에 고정합니다. 스트리밍의 유연함을 얻으면서도 통짜 암호화의 무결성을 잃지 않는 균형이 여기서 만들어집니다.

이 청크들을 실제로 어떻게 받아 복호화 재생하는지는 MediaSource 암호화 스트리밍에서, 청크를 암호화하는 파일 키가 어디서 오는지는 HKDF 도메인 분리 서브키에서 다룹니다. 전체 구조는 제로널리지 암호화 미디어 클라우드 사례에 있습니다.

자주 묻는 질문

AAD가 정확히 무엇을 막나요?

AAD는 청크의 위치 정보를 인증 태그 계산에 묶어, 청크를 다른 자리로 옮기거나 다른 파일의 청크로 바꿔치기하거나 순서를 뒤섞는 조작을 복호화 단계에서 탐지하게 만듭니다. AAD가 기대값과 다르면 태그 검증이 실패해 복호화가 거부되므로, 각 청크는 자기가 어느 파일의 몇 번째 조각인지를 암호학적으로 증명하게 됩니다.

왜 AES-GCM 대신 XChaCha20-Poly1305인가요?

XChaCha20의 24바이트 논스는 청크마다 무작위 논스를 안전하게 쓸 수 있을 만큼 넓어, 순차 논스 상태 관리 없이도 충돌 걱정이 사실상 없습니다. AES-GCM은 96비트 논스라 대량 무작위 사용 시 충돌 위험을 계산해야 하고 스트리밍 복호화와도 잘 맞지 않습니다. 파일이 많은 미디어 클라우드에서는 넓은 논스 공간이 실질적 이점입니다.

청크 포맷을 나중에 바꿀 수 있나요?

바꾸기 매우 어렵습니다. 이미 저장된 모든 파일이 현재의 청크 포맷을 따르고 있어서 인코딩 규칙을 바꾸면 기존 파일을 복호화할 수 없게 됩니다. 그래서 파일 식별자 길이와 인덱스 바이트 순서, 논스 위치 같은 세부를 초기에 확정해 불변 계약으로 관리하고 변경이 필요하면 버전을 나누는 방식으로 접근해야 합니다.

#XChaCha20#Poly1305#AAD#청크암호화#무결성

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

무료 상담 신청