1. CMS란? - Cryptographic Message Syntax 개요
파일이나 메시지를 주고받을 때 보안을 우려하는 사람은 자연스럽게 다음과 같은 질문을 떠올린다.
"이 내용을 누가 만들었는지 증명할 수 있을까?"
"중간에 내용이 바뀌지 않았다는 것을 어떻게 알 수 있을까?"
"이 내용을 특정 인물에게만 보여주고 싶은데, 어떻게 할 수 있을까?
CMS(Cryptographic Message Syntax)는 이러한 요구를 하나의 통일된 포장 규칙으로 해결하도록 만든 표준이다. 특정 암호 알고리즘의 이름이 아니라, 데이터를 어떤 📦 상자에 어떤 라벨과 증빙을 붙여 담을지를 정한 메시지 표현 형식이라고 이해하면 쉽다. 동일한 규칙을 따르기만 하면 서로 다른 시스템과 구현 사이에서도 일관되게 만들고 해석할 수 있다는 점이 핵심이다.

CMS가 목표로 하는 보안 속성은 다음과 같다.
- ✅ 무결성 (Integrity) : 내용이 전송 혹은 보관 중에 변조되지 않았음을 확인한다.
- ✅ 기밀성 (Confidentiality) : 허가된 사람만 내용을 열람할 수 있도록 한다.
- ✅ 인증 (Authentication) : 누가 작성했는지 검증한다.
- ✅ 부인 방지 (Non-Repudiation) : 작성 사실을 사후에 부인하기 어렵도록 증거 확보한다.
즉, 원본 데이터를 목적에 맞게 표준화된 방식으로 포장하고, 수신자는 그 포장을 규칙에 따라 열어 검증함으로써 위 속성들을 확보하는 개념이다. 전자우편, RESTful API, 저장 매체 등 전달 수단과 무관하게 같은 규격으로 표현하고 검증할 수 있다는 점에서 CMS는 응용 영역 전반의 공통 기반을 제공한다.
2. CMS 이해를 위한 배경 지식 한눈에 보기
해당 챕터는 CMS의 큰 그림을 이해하는 데 꼭 필요한 핵심만 간단히 요약한다. 각 소주제는 링크를 통해 자세한 내용을 확인할 수 있다. 이미 알고 있는 내용이라면 생략해도 좋다.
2-1. 공개 키 암호화 방식
공개 키 암호화 방식(Public Key Cryptography)은 서로 다른 두 개의 키(공개 키와 개인 키)를 사용한다. 두 키는 수학적으로 연결되어 있어 다음을 수행한다.
* 전자 서명 : 작성자는 개인 키로 서명하고, 검증자는 공개 키로 서명을 검증한다. 이를 통해 "누가 만들었는가(출처)"와 "중간에 바뀌지 않았는가(무결성)"을 확인할 수 있다.
* 암호화 : 원본 메시지를 숨길 때는 수신자의 공개 키로 암호화하고, 수신자는 자신의 개인 키로 복호화한다.
즉, 본인만이 안전하게 보관해야 하는 개인 키와 대중에게 공개되는 공개 키의 쓰임새가 서로 다르다.
2-2. 대칭 키 암호화 방식
대칭 키 암호화 방식(Symmetric Key Cryptography)은 하나의 동일한 키로 암·복호화를 수행한다.
* 장점 : 처리 속도가 빠르고 대용량 데이터에 적합하다.
* 단점 : 키를 상대에게 안전하게 전달해야 한다는 문제가 있다.
2-3. 해시 함수
해시 함수(Hash Function)는 임의 길이 입력을 고정 길이의 지문(다이제스트)으로 변환하는 일방향 함수이다. 일반적으로 SHA-256 이상의 해시를 사용한다.
* 주요 특징 : 일방향성, 충돌 저항성 등
* 용도 : 무결성 확인, 전자서명 입력 축소 등
2-4. X.509 인증서, ASN.1, DER
* X.509 : 디지털 인증서에 무엇을 담을지를 정한 설계도이며, "이 공개 키가 특정 주체(Subject)에게 속한다."는 사실을 발급자(Issuer)의 서명으로 보증하는 전자 문서다. 인증서의 구조는 기본 필드와 확장 필드로 구분된다.
* ASN.1 : 그 설계도를 어떻게 표현할지 정한 문법이며, 인증서와 CMS 등은 ASN.1으로 표현된다.
* DER : 문법에 의해 표현된 내용을 바이트로 바꿀 때 항상 같은 값이 나오게 하는 규칙이며, ASN.1으로 표현된 내용은 주로 DER로 인코딩되어 파일로 사용된다.
2-5. 인증서 체인
인증서는 보통 체인(chain)으로 신뢰가 성립된다.
* 체인 구성 : Entity Certificate → Intermediate CA → Root CA(Trust Anchor)
* 검증 개념 : 각 단계의 상위 인증서 서명이 유효한지, 유효기간 및 용도가 정책에 부합하는지 확인한다. 최종적으로 사용자의 신뢰 저장소(trust store)에 있는 루트 CA를 기준으로 신뢰 여부가 결정된다.
2-6. CRL & OCSP
서명자 인증서가 폐지(Revocation)되었는지 확인하는 대표적 방법은 두 가지이다.
* CRL(Certificate Revocation List) : 인증 기관(CA)이 주기적으로 배포하는 폐지 목록 파일을 내려받아 확인한다. 인증서의 확장필드 CRL DP에 관련 위치 정보가 포함된다.
* OCSP(Online Certificate Status Protocol) : 특정 인증서의 현재 상태를 온라인으로 질의하고 응답 받는 형식으로 확인한다. 인증서의 확장필드 AIA에 관련 위치 정보가 포함된다.
3. CMS 활용 시 전체 흐름
보안 목적을 지닌 원본 메시지를 표준 방식으로 포장하고 해석하는 CMS 적용 흐름은 다음과 같다.

- 1️⃣ 단계 : 송신자는 무결성, 기밀성, 인증, 부인 방지 중 무엇을 보장할지 결정한다.
- 2️⃣ 단계 : 송신자는 정한 목표에 맞춰 어떤 상자에 담을지 결정한다.
- 3️⃣ 단계 : 송신자는 상자에 담기 위해 필요한 입력값을 모은다.
- 4️⃣ 단계 : 송신자는 표준에서 정한 구조와 규칙에 따라 입력값을 상자에 담는다.
- 5️⃣ 단계 : 송신자는 생성된 CMS 상자를 전달 수단을 통해 전달한다.
- 6️⃣ 단계 : 수신자는 CMS 상자를 해제하고 목적에 맞게 검증하여 송신자의 보안 목적을 달성한다.
- 7️⃣ 단계 : 검증을 통과한 메시지를 업무 로직에 넘겨 활용하고, 감사 및 보관 정책에 따라 사후 처리한다.
4. CMS 콘텐츠 타입 6가지 상세 내용
3장에서 "어떤 상자에 담을지" 결정하는 단계는 CMS가 정의한 콘텐츠 타입(content type) 중 하나를 선택하는 과정이다. CMS는 다음 여섯 가지 표준 타입을 제공한다.
- Data
- SignedData
- EnvelopedData
- DigestedData
- EncryptedData
- AuthenticatedData
각 타입은 "무엇을 증빙하거나, 무엇을 보호하는지"에 초점이 다르다. 따라서, 이 장의 목적은 "어떤 상황에서 어떤 타입을 고르면 좋은가"에 답할 수 있도록 정의, 포맷 요약, 사용 목적을 간결하게 정리하는 데 있다.
4-1. 기본 원본 데이터 Data
※ 정의
Data는 이름 그대로 원본 바이트열(Octet String)을 담는 가장 기초적인 콘텐츠 타입이다. 자체적으로 무결성, 인증, 기밀성을 제공하지 않으며, 보통은 다른 타입의 내용물(payload)로 사용된다.
※ 포맷 요약
ContentInfo
├─ contentType : id-data (1.2.840.113549.1.7.1)
└─ content : Data
※ 사용 목적
- ✅ 서명 및 암호화의 원본 메시지
Data를 내용물(payload)로 두고, 바깥에 SignedData 또는 EnvelopedData 등 다른 타입을 적용해 필요한 보안 속성을 부여한다.
- ✅ 단독 전달(예외적)
Data만으로도 전송할 수는 있으나, 보안 속성이 전혀 없음에 유의해야 한다. 전송 구간 보안을 신뢰하거나, 단순 저장 및 교환이 목적일 때만 제한적으로 사용된다.
4-2. 전자서명으로 무결성과 인증을 수행하는 SignedData
※ 정의
SignedData는 원본 데이터가 변조되지 않았고(무결성), 메시지를 만든 작성자가 누구인지 검증(인증)할 수 있게 하는 포맷이다. 원본 데이터에 전자 서명을 부여해 하나의 꾸러미로 만들며, 필요하면 검증에 쓰일 인증서와 폐지 정보도 함께 담을 수 있다. 이 콘텐츠 타입은 기밀성을 제공하지 않는다. 기밀성이 추가로 요구되면 EnvelopedData와의 중첩(서명 후 암호화 등)을 고려한다.
즉, SignedData는 무결성과 작성자 인증을 수행해야 할 때, 서명값과 더불어 검증에 필요한 정보를 담는 메시지 포맷이다.
※ 포맷 요약
ContentInfo
├─ contentType : id-signedData (1.2.840.113549.1.7.2)
└─ content : SignedData
├─ version
├─ digestAlgorithms : 사용된 해시 알고리즘의 목록
├─ encapContentInfo
│ ├─ eContentType : 원본 데이터의 종류
│ └─ eContent : 실제 원본 데이터
├─ certificates : 서명 검증에 필요한 인증서 목록
├─ crls : 인증서 폐지 목록
└─ signerInfos : 서명자들의 정보와 서명 값 목록
├─ version
├─ sid : 서명자 식별 정보
├─ digestAlgorithm : 사용된 해시 알고리즘 지정
├─ signedAttrs : 서명 값에 포함되어 보호받는 속성
├─ signatureAlgorithm : 실제 서명에 사용된 알고리즘 지정
├─ signature : 실제 서명값
└─ unsignedAttrs : 서명 값에 포함되지 않는 속성
※ 사용 목적
- 문서, 바이너리 등 무결성과 출처 증명이 필요할 때
- 여러 서명자나 승인 단계가 있는 문서를 처리할 때 (동일 객체에 복수 서명)
- 서명 후 암호화가 필요할 때 (무결성과 인증 확보 후 기밀성까지 요구되는 경우)
- 시간 증거와 부인 방지를 강화해야 할 때
※ 참고 글 : 📎 CMS SignedData 정리 : 개념 및 구조부터 동작 원리와 활용 예시까지
4-3. 여러 수신자를 대상으로 기밀성을 제공하는 EnvelopedData
※ 정의
EnvelopedData는 원본 데이터를 대칭 키로 암호화하고, 그 대칭 키를 수신자별 공개 키로 암호화하여 기밀성을 제공하는 포맷이다. 하나의 메시지에 여러 수신자를 지정할 수 있으며, 각 수신자는 자신의 개인 키로 대칭 키를 복구한 뒤 본문을 복호화한다. 이 콘텐츠 타입은 인증과 무결성은 제공하지 않는다. 해당 속성이 필요하면 SignedData와 중첩하여 사용한다.
즉, EnvelopedData는 여러 수신자에게 동일한 데이터의 기밀성을 제공해야 할 때, 암호화된 데이터와 복호화에 필요한 정보를 함께 담는 메시지 포맷이다.
※ 포맷 요약
ContentInfo
├─ contentType : id-envelopedData (1.2.840.113549.1.7.3)
└─ content : EnvelopedData
├─ version
├─ originatorInfo : 발신자 정보
├─ recipientInfos : 각 수신자를 위한 정보(데이터를 복호화할 대칭 키를 어떻게 전달할지에 따라 방식이 다르다.)
│ ├─ KeyTransRecipientInfo
│ ├─ KeyAgreeRecipientInfo
│ ├─ KEKRecipientInfo
│ └─ PasswordRecipientInfo
│
├─ encryptedContentInfo
│ ├─ contentType : 원본 데이터의 종류
│ ├─ contentEncryptionAlgorithm : 사용된 대칭 키 암호화 알고리즘
│ └─ encryptedContent : 암호화된 실제 원본 데이터
└─ unprotectedAttrs : 암호화되지 않은 속성
※ 간단 동작 개념
- 송신자는 수신자 A와 B에게 비밀 내용을 보내려고 한다.
- 1️⃣ 단계 : 송신자는 (일회성)대칭 키를 만들고, 그 키로 원본 메시지를 암호화한다.
- 2️⃣ 단계 : 송신자는 각 수신자의 공개 키로 대칭 키를 암호화한다.
- 3️⃣ 단계 : 송신자는 표준 구조에 따라 EnvelopedData를 구성한다.
- 4️⃣ 단계 : 송신자는 EnvelopedData를 수신자 A와 B에게 전달한다.
- 5️⃣ 단계 : 수신자 A와 B는 각자 자신의 개인 키로 자기 몫의 대칭 키를 복구한다.
- 6️⃣ 단계 : 수신자 A와 B는 복구한 대칭 키로 암호화된 원본 메시지를 복호화하여 내용을 확인한다.
※ 사용 목적
- 여러 수신자에게 동일한 원문 메시지를 안전하게 배포해야 할 때
4-4. 해시를 기반으로 무결성만 제공하는 DigestedData
※ 정의
DigestedData는 원본 메시지에 대한 해시값(다이제스트)을 계산하여 함께 넣어주는 형식이다. 수신자는 전달받은 원본 메시지로 같은 해시 알고리즘을 적용해 무결성만 확인한다. 이 콘텐츠 타입은 인증과 기밀성을 제공하지 않는다. 따라서 공격자가 본문과 해시를 함께 바꾸어 보냈다면 수신자는 이를 탐지하지 못한다. 신뢰된 전달 경로에서 간단한 무결성 확인을 수행할 때만 적합하다.
※ 포맷 요약
ContentInfo
├─ contentType : id-digestedData (1.2.840.113549.1.7.5)
└─ content : DigestedData
├─ version
├─ digestAlgorithm : 사용된 해시 알고리즘
├─ encapContentInfo
│ ├─ eContentType : 원본 데이터의 종류
│ └─ eContent : 원본 데이터
└─ digest : 계산된 해시값 (무결성 검증용)
※ 사용 목적
- TLS나 전용망 등 이미 보호된 채널에서 전달 중 오류나 의도치 않은 변형을 간단히 확인할 때
- 무결성만 간단하게 확인하고 싶을 때
※ 간단 동작 개념 : 📎 DigestedData를 통한 무결성 확인 과정
4-5. 기밀성을 제공하는 EncryptedData
※ 정의
EncryptedData는 본문을 하나의 대칭 키로 암호화하여 기밀성을 보장하기 위한 포맷이다. 수신 대상에게 키를 배포하는 방법은 이미 해결되었다고 가정한다. 즉, 해당 객체에는 수신자 정보가 포함되지 않는다.
즉, EncryptedData는 키 분배 문제를 시스템 외부 정책으로 해결한 뒤, 암호화된 원본 데이터와 복호화에 필요한 정보를 담는 메시지 포맷이다.
※ 포맷 요약
ContentInfo
├─ contentType : id-encryptedData (1.2.840.113549.1.7.6)
└─ content : EncryptedData
├─ version
├─ encryptedContentInfo
│ ├─ contentType : 원본 데이터의 종류
│ ├─ contentEncryptionAlgorithm : 사용된 대칭 키 암호화 알고리즘
│ └─ encryptedContent : 암호화된 실제 원본 데이터
└─ unprotectedAttrs : 암호화되지 않은 속성
※ 사용 목적
- 수신자를 여러 명 한 객체에 담을 필요가 없으나 기밀성이 요구되는 경우
- 키 분배와 키에 대한 접근 제어가 시스템 정책으로 별도 보장되는 환경에서 사용
4-6. 공유 대칭 키 기반의 MAC 인증과 무결성을 제공하는 AuthenticatedData
※ 정의
AuthenticatedData는 원본 메시지에 메시지 인증 코드(MAC, Message Authentication Code)를 붙여, 전송 중 내용이 바뀌지 않았는지와 보낸 쪽이 키를 공유한 당사자인지 확인할 수 있는 포맷이다. MAC은 공유된 대칭 키로 계산하는 짧은 검증값이며, 수신자는 같은 키로 다시 MAC을 계산해 전달받은 MAC과 일치 여부를 확인한다. 특성 상 이 콘텐츠 타입은 무결성과 당사자 인증을 제공하지만, 기밀성과 부인 방지는 제공하지 않는다.
즉, AuthenticatedData는 빠르고 간단한 무결성 및 당사자 인증이 필요할 때, MAC과 검증 정보를 담는 메시지 포맷이다.
※ 포맷 요약
ContentInfo
├─ contentType : id-ct-authData (1.2.840.113549.1.9.16.1.2)
└─ content : AuthenticatedData
├─ version
├─ originatorInfo : 발신자 정보
├─ recipientInfos : 각 수신자를 위한 정보(MAC 키를 어떻게 전달할지에 따라 방식이 다르다.)
│ ├─ KeyTransRecipientInfo
│ ├─ KeyAgreeRecipientInfo
│ ├─ KEKRecipientInfo
│ └─ PasswordRecipientInfo
│
├─ macAlgorithm : MAC 생성 알고리즘
├─ digestAlgorithm : 사용된 해시 알고리즘
├─ encapContentInfo
│ ├─ eContentType : 원본 데이터 종류
│ └─ eContent : 원본 데이터
├─ authAttrs : 인증된 속성
├─ mac : 계산된 MAC 값
└─ unauthAttrs : 인증되지 않은 속성
※ 간단 동작 개념
- 송신자는 수신자 A와 B에게 무결성을 확인할 수 있는 메시지를 보내려고 한다.
- 1️⃣ 단계 : 송신자는 (일회성) 대칭 키로 원본 메시지의 MAC을 계산한다.
- 2️⃣ 단계 : 송신자는 각 수신자의 공개 키로 그 대칭 키를 암호화한다.
- 3️⃣ 단계 : 송신자는 표준 구조에 따라 AuthenticatedData를 구성한다.
- 4️⃣ 단계 : 송신자는 AuthenticatedData를 수신자 A와 B에게 전달한다.
- 5️⃣ 단계 : 수신자 A와 B는 각자 자신의 개인 키로 자기 몫의 대칭 키만 복구한다.
- 6️⃣ 단계 : 수신자 A와 B는 복구한 대칭 키로 원본 메시지의 MAC을 다시 계산해 송신자가 보낸 MAC과 비교한다. 일치하면 변조 없음으로 판단한다.
※ 사용 목적
- 키를 공유한 당사자 간의 인증이 필요할 때
- 무거운 서명보다 간단하고 빠른 무결성 보호가 필요할 때
5. 마무리
CMS(Cryptographic Message Syntax)는 보안 목적을 지닌 메시지를 표준 규칙에 따라 포장하고 해석하는 문법이다. 전송 수단에 구애받지 않고, 무결성∙기밀성∙인증∙부인 방지와 같은 속성을 콘텐츠 타입으로 선택∙조합하는 방식으로 달성한다. 실무에서는 먼저 "무엇을 보장할 것인가"를 분명히 한 뒤, 그 목적에 맞는 타입을 고르는 것이 가장 중요하다.
CMS의 콘텐츠 타입별 특징은 다음과 같다.
| 콘텐츠 타입 | 특징 |
| Data | 원본 바이트를 그대로 담는 기본형이다. 보호 기능은 없다. |
| SignedData | 전자서명으로 무결성과 작성자인증을 제공한다. 환경에 따라 부인 방지까지 충족할 수 있다. |
| EnvelopedData | 본문을 대칭 키로 암호화하고, 그 키를 수신자별 키 래핑해 여러 수신자에게 기밀성을 제공한다. |
| DigestedData | 해시(다이제스트)로 무결성만 확인한다. 공격자가 본문과 해시를 바꾸면 탐지할 수 없다. |
| EncryptedData | 키 분배를 메시지 밖에서 해결한다는 전제하에, 본문만 암호화하여 기밀성 제공(수신자 정보 없음). |
| AuthenticatedData | 공유 대칭 키로 계산한 MAC을 붙여 무결성을 확인하고 당사자 인증을 제공한다. |
요약하면, 서명은 무결성과 인증을, 암호화는 기밀성을, MAC은 빠른 무결성 처리에 초점을 둔다. 필요에 따라 이들을 중첩하여 사용할 수 있다. 예컨대 서명 정보를 포함한 전체 묶음을 다시 암호화하는 "서명 후 암호화" 방식은 서명 메타데이터까지 숨길 수 있어 널리 쓰인다.
결론적으로 보안 목적을 정의하고 그에 맞는 CMS 콘텐츠 타입을 선택한다면, 채널과 구현이 달라도 일관된 방식으로 생성 및 검증할 수 있다. 시스템 전반의 상호 운용성과 보안 수준을 안정적으로 높일 수 있다.
6. 참고 자료 및 표준 문서
- RFC 5652 - Cryptographic Message Syntax (CMS)
'보안 > 전자 서명' 카테고리의 다른 글
| CMS SignedData 정리 : 개념 및 구조부터 동작 원리와 활용 예시까지 (0) | 2025.07.21 |
|---|---|
| 전자 서명이란? 기반 지식부터 동작 원리까지 이해하기 (0) | 2025.03.23 |
