보안/전자 서명 / / 2025. 3. 26. 17:13

CMS(Cryptographic Message Syntax) 내용 정리 - 전체 흐름과 6가지 콘텐츠 타입

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 적용 흐름은 다음과 같다.

 

< 송신자 닝닝이는 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)
    • §4 "Data Content Type" 
    • §5 "Signed-data Content Type"
    • §6 "Enveloped-data Content Type"
    • §7 "Digested-data Content Type"
    • §8 "Encrypted-data Content Type"
    • §9 "Authenticated-data Content Type"

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유