이 글은 IEEE 1609.2의 SPDU가 어떻게 만들어지고(서명), 수신 측에서 어떻게 검증되어 valid / invalid로 판정되는지를 정리한다.
이 글의 흐름
- SPDU가 무엇이고 어떻게 생겼는가
- SDS가 제공하는 서비스와 수신 처리 흐름
- 송신 : 서명된 SPDU 생성
- 수신 ① : 전처리
- 수신 ② : 서명 검증
- 수신 ③ : 유효성 판단 — 세 가지 기준
- ~ 9. 각 기준 상세 (일관성 · 관련성 · 핵심 필드)
- 이 모든 설정값이 모이는 곳 : 보안 프로파일
1. SPDU 개요
SPDU (Security Services Protocol Data Unit) 전송 전에 WAVE 보안 서비스(SDS)에 의해 처리된 프로토콜 데이터 단위. 보안 서비스를 사용하는 SDEE 인스턴스 간에 교환되는 데이터그램.
- 목적
- 내용의 암호학적 보호
- 다른 SPDU의 올바른 처리를 위한 보안 관리 정보 교환
SPDU 유형
Ieee1609Dot2Content의 CHOICE로 표현된다.
| 유형 | 의미 |
|---|
unsecuredData | 보호되지 않은 데이터 (다른 SPDU 안에 담기는 원본 PDU 등) |
signedData | 서명된 데이터 |
encryptedData | 암호화된 데이터 |
signedCertificateRequest | 서명된 인증서 요청 |
signedX509CertificateRequest | X.509 인증서로 서명된 인증서 요청 |
- SPDU는 중첩될 수 있다.
- 예) 서명 후 암호화 :
encryptedData → (복호화) → signedData → unsecuredData
Signed SPDU의 구조
- 이 글에서 계속 등장하는 구조다.
tbsData가 서명 대상이고, signer는 서명 인증서를 가리키며, signature가 서명값이다.
2. SDS가 제공하는 SPDU 처리 서비스
- SDEE(애플리케이션)는 SDS에
.request로 요청하고, SDS는 .confirm으로 결과를 돌려준다.
| 서비스 | 방향 | 하는 일 |
|---|
| Sec-SignedData | 송신 | PDU에 서명하여 signed SPDU 생성 |
| Sec-EncryptedData | 송신 | PDU를 암호화하여 encrypted SPDU 생성 |
| Sec-SecureDataPreprocessing | 수신 | SPDU 전처리 (유형 파악, 정보 추출, 관리 정보 처리) |
| Sec-SignedDataVerification | 수신 | signed SPDU 유효성 검증 |
| Sec-EncryptedDataDecryption | 수신 | encrypted SPDU 복호화 |
수신 처리 흐름
- 전처리와 검증을 분리한 이유
- 서명 검증은 비싼 연산이다.
- 먼저 가볍게 정보를 뽑아 검증할 필요가 없는 SPDU를 미리 걸러내기 위함이다.
- 예) 관심 없는 PSID, 너무 먼 위치의 메시지
3. 서명된 SPDU 생성 (Signed SPDU Generation)
한 줄 요약 : ToBeSignedData를 정규화·COER 인코딩 → 해시 → ECDSA 서명 → SignedData 구성
인증서 기반 서명, 내부 payload 기준
입력
| 입력 | 내용 | SPDU 포함 여부 |
|---|
| Application PDU | 전송할 애플리케이션 데이터 (예: BSM) | 포함 (payload) |
| PSID 등 헤더 정보 | 서비스 식별자, 생성 시각 등 | 포함 (headerInfo) |
| Signing Certificate | 서명자의 권한·공개키가 담긴 인증서 | 포함 (signer에 digest 또는 인증서 자체) |
| Private Key | 서명용 개인키. SDEE는 CMH로만 가리킴 | 포함되지 않음 |
생성 절차
| 단계 | 하는 일 | 비고 |
|---|
| 1. 요청 | SDEE가 Sec-SignedData.request로 PDU, PSID, CMH, 옵션을 전달 | 옵션 : 생성 시각 포함 여부, signer 표현 방식 등 |
| 2. payload 구성 | PDU를 Ieee1609Dot2Data { unsecuredData }로 감싸 payload.data에 넣음 | 외부 payload 방식이면 해시만 extDataHash에 |
| 3. headerInfo 구성 | psid, generationTime 및 프로파일이 요구하는 선택 필드 | expiryTime, generationLocation 등 |
| 4. tbsData 구성 | ToBeSignedData { payload, headerInfo } | 서명 대상 |
| 5. 정규화 + 인코딩 | tbsData를 정규화한 뒤 COER로 인코딩 | 아래 “정규화” 참고 |
| 6. 해시 | H( H(tbsData) ‖ H(서명자 식별 입력) ) | 아래 “해시 계산” 참고 |
| 7. ECDSA 서명 | CMH가 가리키는 개인키로 해시값에 서명 | HSM 안에서 수행 |
| 8. signer 결정 | digest / certificate / self 중 하나 | 보안 프로파일에 따름 |
| 9. 조립 · 반환 | SignedData를 조립해 Sec-SignedData.confirm으로 반환 | |
1
2
3
4
5
6
7
8
9
| Ieee1609Dot2Data {
protocolVersion 3,
content signedData {
hashId sha256,
tbsData { payload, headerInfo },
signer digest / certificate / self,
signature ecdsaNistP256Signature { rSig, sSig }
}
}
|
ECDSA는 서명마다 새로운 임의의 nonce(k) 를 사용해야 한다. 재사용하면 개인키가 노출된다.
해시 계산
1
| H( H(tbsData의 COER 인코딩) ‖ H(서명자 식별 입력) )
|
H : hashId가 지정한 해시 함수 (예: SHA-256). 암호화가 아니다.‖ : 두 바이트열을 이어붙이기(concatenation). “또는”이 아니다.- 두 입력은 항상 둘 다 필요하다.
| signer 유형 | 서명자 식별 입력 |
|---|
| certificate / digest | 서명 인증서의 COER 인코딩 |
| self (자체 서명) | 빈 문자열 |
1
2
3
4
5
| ① h1 = SHA-256( tbsData의 COER 바이트 ) → 메시지 지문 (32B)
② h2 = SHA-256( 서명 인증서의 COER 바이트 ) → 인증서 지문 (32B)
③ m = h1 ‖ h2 → 64B로 이어붙임
④ e = SHA-256( m ) → 최종 지문 (32B)
⑤ signature = ECDSA_Sign( 개인키, e ) → 키가 쓰이는 곳은 여기뿐
|
왜 인증서 해시까지 함께 서명할까?
- 서명 대상에
H(서명 인증서)를 포함하면 서명이 특정 인증서에 묶인다. - 공격자가
signer를 같은 공개키를 가진 다른 인증서(예: 권한이 다른 인증서)로 바꿔치기하면 해시가 달라져 서명 검증이 실패한다. - 특히 implicit 인증서는 공개키가 인증서 내용으로부터 재구성되므로, 인증서와 서명을 묶는 것이 중요하다.
정규화 (Canonicalization)
- ASN.1 / OER에서는 같은 정보를 여러 방식으로 표현할 수 있다.
- 예) 타원곡선 점(
EccP256CurvePoint)은 x-only, compressed-y-0/1, uncompressedP256 중 하나로 표현 가능
- 해시는 바이트 단위로 계산되므로, 표현이 다르면 같은 정보라도 해시가 달라진다.
- 그래서 해시 전에 정해진 표준 형식(canonical form)으로 변환한 뒤 COER로 인코딩한다.
- 예) 인증서의 공개키는 압축(compressed) 형태, 서명의 r 값은 x-only 형태
- 재귀적으로 적용된다. 구조체 안의 구조체도 정규화 규칙에 따라 변환된다.
송신 측과 수신 측이 바이트 단위로 같은 입력을 해시해야 서명이 맞는다. 정규화가 필요한 이유다.
4. 전처리 (Preprocessing)
- Peer SDS들이 관리 정보를 교환하고, SDEE가 SPDU를 더 처리할지 결정하는 데 필요한 정보를 추출한다.
| 항목 | 내용 |
|---|
| 요청 | Sec-SecureDataPreprocessing.request |
| 응답 | Sec-SecureDataPreprocessing.confirm — SPDU 유형, (signedData면) PSID, SSP, generationTime, 지리적 유효 영역 등 |
| 필수 제공 | P2PCD를 지원하거나, signer를 digest 형태로 허용하는 경우 |
| 선택 제공 | 그 외의 경우 |
- digest 지원 시 필수인 이유
- digest만 받으면 SSME에 해당 인증서가 있는지 확인하고, 없으면 P2PCD 요청을 준비해야 하기 때문
5. 서명 검증 (Signature Verification)
- SDEE가 요청하면 SDS가 검증 키를 확보하고 해시를 다시 계산해 서명을 검증한다.
① 검증 키 확보
signer 유형에 따라 서명 인증서와 그 공개키를 확보한다.
signer | 서명 인증서 확보 방법 |
|---|
digest (HashedId8) | SSME에서 같은 HashedId8의 인증서를 조회 |
certificate | SPDU에 포함된 인증서를 사용 (SSME에도 저장해 이후 digest 수신에 대비) |
self | 인증서 없음. 공개키는 SDEE 명세에 정의된 방법으로 확보 |
- 공개키 확보
- explicit 인증서 :
verifyKeyIndicator.verificationKey를 그대로 사용 - implicit 인증서 :
reconstructionValue와 발급자 공개키로 재구성
- SSME에서는 인증서와 함께 체인 검증 상태(Trust Anchor까지 연결되는지, 폐기되지 않았는지)도 확인한다.
digest인데 SSME에 인증서가 없으면 검증할 수 없다. → P2PCD로 이웃에게 인증서를 요청한다.
P2PCD (Peer-to-Peer Certificate Distribution)
- 모르는 인증서를 주변 단말에게 직접 요청해 받는 메커니즘
- 인증 기관(CA) 서버를 거치지 않고, 통신 중인 이웃(peer)끼리 인증서를 주고받는다.
- 평소
signer를 8바이트 digest로 보내 크기를 줄이는 대신, 생길 수 있는 “인증서 누락”을 메우는 역할이다.
- 인증서가 없는 경우의 예 : 막 통신 범위에 들어옴, 전체 인증서가 담긴 메시지를 놓침, 상대가 인증서를 교체함
1
2
3
4
| ① 수신 측 : digest의 인증서가 SSME에 없음 → 검증 불가
② 수신 측 : 다음에 보내는 SPDU의 headerInfo.p2pcdLearningRequest에 그 인증서의 HashedId3(3바이트)를 실어 요청
③ 원 송신자(또는 그 인증서를 가진 이웃) : 이후 SPDU에 해당 인증서를 실어 응답
④ 수신 측 : 받은 인증서를 SSME에 저장 → 이후 digest로 오는 메시지도 검증 가능
|
관련 필드 (headerInfo) | 역할 |
|---|
p2pcdLearningRequest | 모르는 인증서의 HashedId3로 요청 |
inlineP2pcdRequest | 모르는 인증서 여러 개를 HashedId3 목록으로 요청 |
requestedCertificate | 요청받은 인증서를 SPDU에 실어 제공 (인라인 응답) |
- 처리 주체 : 상위 계층 보안 서비스인 P2PCDE(P2PCD Entity)
- 요청은 3바이트, 응답은 원래 보내던 메시지에 얹어 보내므로 별도의 큰 트래픽 없이 동작한다.
② 해시 재계산
- 송신 측과 똑같은 방식으로 해시를 다시 계산한다. 해시 알고리즘은 SPDU의
hashId를 따른다.
1
| H( H(tbsData의 정규화된 COER 인코딩) ‖ H(서명 인증서의 COER 인코딩) )
|
③ ECDSA 검증
- ①의 공개키로, ②의 해시값에 대해
signature를 검증한다. - 결과는
Sec-SignedDataVerification.confirm으로 SDEE에 반환된다.
| 결과 | 의미 |
|---|
| PASS | tbsData와 서명 인증서가 서명 당시와 동일함 → 위·변조 없음 |
| FAIL | tbsData 또는 signer가 바뀌었거나, 다른 키로 서명됨 |
생성과 검증 비교
| 단계 | 생성 (송신) | 검증 (수신) |
|---|
| 키 | 개인키 (CMH, HSM 내부) | 공개키 (서명 인증서에서 확보) |
| 서명 인증서 | 자신의 인증서 | signer로 찾음 (digest → SSME 조회) |
| 해시 | H( H(tbsData) ‖ H(인증서) ) 계산 | 같은 값을 다시 계산 |
| ECDSA | 서명 생성 → signature | signature 검증 → PASS / FAIL |
서명 검증 PASS는 “위·변조되지 않았다” 는 뜻일 뿐, SPDU가 유효하다는 뜻은 아니다. valid가 되려면 다음 장의 세 가지 기준을 모두 통과해야 한다.
6. 유효성 판단 : 세 가지 기준
1
| valid = Consistency ∧ Relevance ∧ No unsupported Critical Fields
|
| 기준 | 판단 기준 | 확인 항목 | 상세 |
|---|
| Consistency (일관성) | 수신자 상태와 무관하게 SPDU 내용으로 판단 | 형식 · 서명 · 체인 · 폐기 상태 PSID · 생성 시각 · 지역 (인증서와 대조) Payload·SSP · 미래 정보 · Asserted data | 7장 |
| Relevance (관련성) | 수신자의 현재 상태(시각, 위치, 수신 기록) 기준 | Freshness · Future generation Expiry · Location Replay · Certificate expiry | 8장 |
| Critical Fields (핵심 필드) | 유효성 판단에 필요한 핵심 필드를 해석·지원할 수 있는가 | 너무 긴 필드, 너무 많은 항목, 너무 깊은 중첩, 모르는 식별자 | 9장 |
일관성 조건은 누가 언제 검증해도 결과가 같고, 관련성 조건은 받는 쪽의 상황에 따라 결과가 달라진다.
헷갈리기 쉬운 짝
- 같은 “시간”, “위치”라도 무엇과 비교하느냐에 따라 분류가 달라진다.
| 비교 대상 | 분류 | 예 |
|---|
| SPDU의 시각 ↔ 인증서의 기간 | Consistency | 생성 시각이 인증서 유효기간 안인가 |
| SPDU의 시각 ↔ 수신자의 현재 시각 | Relevance | 생성 시각이 지금보다 너무 과거·미래인가 |
| SPDU의 위치 ↔ 인증서의 지역 | Consistency | 생성 위치가 인증서 region 안인가 |
| SPDU의 위치 ↔ 수신자의 현재 위치 | Relevance | 생성 위치가 나와 너무 먼가 |
- 인증서 만료도 같은 원리다.
- 생성 시각이 인증서 유효기간 안인가 → Consistency
- 지금 이 순간 인증서가 만료되었는가 → Relevance
무효 사유
- 왜 무효인지에 대한 정보를 제공할 수 있다.
- 여러 조건을 동시에 위반해도
confirm으로 반환되는 결과에는 하나의 사유만 포함된다.
전체 체크리스트 펼치기
- Consistency
- 형식 : 정의된 ASN.1 구조로 올바르게 생성되었고 내부적으로 모순이 없다.
- 서명 : 서명 인증서(또는 self 공개키)로 서명 검증을 통과한다.
- 체인 : 서명 인증서에서 Trust Anchor까지 유효한 체인이 있다. (체인 길이 한도 이내)
- 폐기 상태 : 체인 내 어떤 인증서도 폐기되지 않았다.
- PSID :
headerInfo.psid가 인증서 appPermissions에 있다. - 생성 시각 :
generationTime이 인증서 validityPeriod 안에 있다. - 지역 :
generationLocation(또는 SPDU가 다루는 지역)이 인증서 region 안에 있다. - 시각 순서 :
generationTime과 expiryTime이 둘 다 있으면 generationTime < expiryTime이다. - 확장 조건 : 인증서
appExtensions가 거는 제약을 만족한다. - Payload·SSP : payload 내용이 인증서의 SSP가 허용하는 범위 안에 있다.
- 미래 정보 : SPDU가 주장하는 시각(
expiryTime 등)이 서명 인증서 유효기간을 벗어나지 않는다. - Asserted data : SPDU에 담긴 다른 SDEE의 데이터도 인증서 권한(PSID)으로 허용된다.
- Relevance
- Freshness : 너무 오래전에 생성되지 않았다.
- Future generation : 너무 미래에 생성된 것으로 표시되지 않았다.
- Expiry :
expiryTime이 지나지 않았다. - Location : 생성 위치가 수신자로부터 너무 멀지 않다.
- Replay : 최근 처리한 SPDU의 복제가 아니다.
- Certificate expiry : 체인 내 모든 인증서가 현재 시각 기준으로 만료되지 않았다.
- Critical Fields
- 유효성 판단에 필요한 모든 핵심 필드를 해석·지원할 수 있다.
7. 일관성 조건 (Consistency Conditions)
| 분류 | 의미 | 예 |
|---|
| 전역 일관성 | 어떤 SDEE가 받든 같은 결과 | 서명, 체인, PSID ↔ 인증서 |
| SDEE별 일관성 | 수신 SDEE에 따라 달라지지만, 로컬 상태(시각·위치)에는 의존하지 않음 | 허용 PSID, 체인 길이 한도, payload 해석 |
- 일부 조건은 항상 적용되고, 나머지는 SDEE 명세(보안 프로파일)에서 적용 여부를 정한다.
7.1 전역 일관성 조건 (Global Consistency)
| 묶음 | 검사 | 확인 내용 | 적용 |
|---|
| 서명·구조 | 형식 | SPDU와 체인 인증서가 표준 구조대로 구성됨 (self-signed는 SDEE 명세가 허용할 때만) | 필수 |
| | 서명·체인 | SPDU 서명 검증 · Trust Anchor까지 체인 검증 · 폐기 여부 | 필수 |
| 인증서와 대조 | PSID | 서명 인증서의 appPermissions가 해당 PSID를 허용 | 필수 |
| | 생성 시각 | 생성 시각을 얻을 수 있고, 그 값이 인증서 유효기간 안 | 필수 |
| | 만료 시각 | 인증서 유효기간 안 | 사용 시 |
| | 지리 정보 | 인증서 region과 정합 | 사용 시 |
| SPDU 내부 | 시각 순서 | generationTime < expiryTime (같아도 invalid) | 둘 다 있을 때 |
| | 확장 조건 | appExtensions에 의한 제약을 만족 | 해당 시 |
사용 시 : Security Profile에서 해당 검사를 하도록 설정되어 있으며, 메시지에 해당 값이 있는 경우
1
2
3
| 서명·구조 → "믿을 수 있는 인증서가 서명했고, 위·변조되지 않았다"
인증서와 대조 → "그 인증서가 이 내용(PSID, 시각, 위치)을 서명할 권한이 있다"
SPDU 내부 → "SPDU 자체에 모순이 없다"
|
서명·구조
- 형식
- SPDU와 체인에 포함된 인증서가 정의된 ASN.1 구조대로 올바르게 생성되었다.
signer가 self인 SPDU는 SDEE 명세가 자체 서명을 허용할 때만 유효하다.
- 서명·체인
- SPDU 서명 검증 : 5장의 과정. 자체 서명이면 공개키는 SDEE 명세에 정의된 방법으로 얻는다.
- 체인 검증 : 서명 인증서에서 알려진 Trust Anchor까지 유효한 체인이 존재한다.
- 체인 내 각 인증서의 서명(또는 implicit 인증서의 재구성)이 올바르다.
- 체인 내 각 인증서의 권한·기간·지역이 발급자 범위 안에 있다.
- 폐기 여부 : 체인 내 어떤 인증서도 폐기되지 않았다. (SSME에 저장된 CRL 정보로 확인)
인증서와 대조
- 보안 봉투(
headerInfo)가 주장하는 내용이 서명 인증서가 허용하는 범위 안에 있어야 한다.
| 검사 | SPDU 쪽 | 인증서 쪽 | 조건 |
|---|
| PSID | headerInfo.psid | appPermissions | PSID가 허용 목록에 있음 |
| 생성 시각 | generationTime | validityPeriod | 유효기간 시작 ≤ 생성 시각 ≤ 유효기간 끝 |
| 만료 시각 | expiryTime | validityPeriod | 만료 시각이 유효기간 안 |
| 지리 정보 | generationLocation | region | 생성 위치가 인증서 지역 안 |
- 생성 시각은 “얻을 수 있어야” 한다.
- 보통
headerInfo.generationTime에서 얻지만, 없다면 SDEE 명세가 정한 다른 방법(예: payload 안의 시각)으로 얻을 수 있어야 한다. - 생성 시각을 알 수 없으면 인증서 유효기간 안에서 서명했는지 판단할 수 없으므로 invalid
- 만료 시각, 지리 정보는 선택 검사다. 값이 있고 프로파일이 정한 경우에만 수행한다.
SPDU 내부
- 인증서와 비교하지 않고, SPDU 안의 값들끼리 모순이 없는지 본다.
- 시각 순서 :
generationTime < expiryTime- 같은 경우도 invalid : 생성되는 순간 만료되는 메시지는 의미가 없기 때문
- 확장 조건 : 인증서의
appExtensions가 거는 추가 제약을 만족해야 한다.- 예)
OperatingOrganizationId 확장이 있는 인증서라면, SPDU에서 얻은 운영 조직 OID가 그 값과 같아야 한다.
7.2 SDEE별 일관성 조건 (SDEE-specific Consistency)
- 같은 SPDU라도 어떤 SDEE가 받느냐에 따라 허용 PSID, 체인 길이 한도, payload 해석 방식이 다르다.
- 그래도 수신자의 현재 시각·위치에는 의존하지 않으므로 관련성이 아니라 일관성 조건이다.
- 누가 검사하느냐에 따라 두 가지로 나뉜다.
- 나누는 기준은 검사에 필요한 정보를 SDS가 가지고 있느냐이다.
- SDS에게 payload는 불투명한 바이트열이다. 그래서 payload 내용과 관련된 검사는 SDEE가 해야 한다.
- 대신 SDS는 검증 결과와 함께 서명 인증서의 PSID, SSP, assurance level, region, appExtensions 등을 SDEE에 돌려주어 SDEE가 비교할 수 있게 한다.
SDS가 검사할 수 있는 조건
| 검사 | 내용 | 예 |
|---|
| PSID 문맥 일치 | SDEE가 요청 시 넘긴 기대 PSID와 headerInfo.psid 비교 | BSM 앱이 받은 SPDU의 PSID가 BSM이 아니면 invalid |
| 체인 인증서 수 | 서명 인증서~Trust Anchor 체인의 인증서 수 < SDEE 한도 | 체인이 길수록 검증 비용·신뢰 경로가 늘어나므로 깊이를 제한 |
SDEE가 직접 검사하는 조건
| 검사 | 내용 | SDEE가 하는 이유 |
|---|
| payload ↔ 인증서 권한 | payload 내용이 인증서의 PSID, SSP, assurance level 범위 안 | SSP 비트의 의미는 SDEE 명세만 안다 |
| 외부 데이터 해시 | extDataHash / omitted 사용 시, 실제 외부 데이터의 해시가 일치 | 외부 데이터는 SPDU 밖에서 전달되어 SDEE만 가진다 |
| 지리 영역 | 점이 아닌 영역 정보가 인증서 region 안 | 영역 정보는 보통 payload 안에 있다 |
| appExtensions | 명세가 요구하면 payload가 인증서 appExtensions와 정합 | payload 해석이 필요하다 |
- 예) 긴급차량 정보를 담은 메시지는 SSP에 긴급차량 권한이 있는 인증서로 서명되어야 한다.
- 단일 지점(
generationLocation)은 headerInfo에 있어 SDS가 검사하며, 이는 전역 일관성의 지리 정보 검사에 해당한다.
SDEE가 직접 검사하는 조건을 빠뜨리면, SDS가 valid로 판정했더라도 SPDU는 실제로는 유효하지 않을 수 있다. SDS의 valid는 SDS가 확인할 수 있는 범위까지의 결과다.
7.3 Payload 관련 추가 조건
- 주장된 데이터 (Asserted data)
- SPDU 안에 다른 SDEE의 데이터가 담긴 경우(운반 SDEE / 포함 SDEE), 두 SDEE의 PSID가 모두 인증서
appPermissions에 있어야 한다.
- 지리 정보 유형
- signed SPDU는 다음 중 하나의 지리 정보 유형을 따른다.
| 유형 | 의미 | 검사 |
|---|
| 전역 (Global) | 지역 제한 없음 | - |
| 영역 (Region) | 특정 지역에 대한 정보 | SDEE별 (지리 영역) |
| 지점 (Point) | 특정 위치(generationLocation)에 대한 정보 | 전역 (지리 정보) |
8. 관련성 조건 (Relevance Conditions)
- 수신 SDEE의 로컬 상태(현재 시각, 현재 위치, 최근 수신 기록)를 기준으로 SDS가 확인한다.
- “너무 오래됨”, “너무 멂” 같은 임계값은 보안 프로파일에서 정의한다.
| 조건 | 사용하는 필드 | 무효 판정 |
|---|
| 신선도 (Freshness) | generationTime | 현재 시각 − 생성 시각 > 허용 기간 (너무 과거) |
| 미래 생성 (Future generation) | generationTime | 생성 시각 − 현재 시각 > 허용 오차 (너무 미래) |
| 만료 (Expiry) | expiryTime | 현재 시각 > 만료 시각 |
| 위치 (Location) | generationLocation | 수신자 위치와의 거리 > 거부 임계 거리 |
| 재전송 (Replay) | tbsData, 서명자 인증서 | 최근 처리한 SPDU와 동일 |
| 인증서 만료 (Certificate expiry) | 체인 내 각 인증서의 validityPeriod | 현재 시각 > 체인 내 어느 인증서의 만료 시각 |
- 신선도와 미래 생성을 합치면,
generationTime은 다음 범위 안에 있어야 한다.
1
2
| 현재 시각 − 허용 기간 ≤ generationTime ≤ 현재 시각 + 허용 오차
(Freshness) (Future generation)
|
- 현재 시각, 위치는 모두 수신 측의 추정치(local estimate)다. GPS·시계 오차를 감안해 허용 범위를 둔다.
- 재전송 탐지
tbsData의 COER 인코딩과 서명자 인증서가 최근 받은 SPDU와 같으면 재전송으로 판단한다.- “최근”의 기준은 신선도의 “너무 과거” 기준과 같은 값을 쓰는 것이 일관된다. 그보다 오래된 재전송은 어차피 신선도에서 걸러지기 때문이다.
- 핵심 정보 필드(critical information field) : signed SPDU의 유효성을 확인할 때 필요한 필드
- 검증자가 핵심 필드의 값과 의미를 결정할 수 없다면, 유효성을 확인할 수 없으므로 invalid로 처리한다.
1
2
3
| 인증서 region = [수신자가 모르는 새로운 지역 표현 방식]
→ 무시하면 : 지역 제한을 확인 안 한 채 valid ← 위험
→ 핵심 필드라면 : 판단 불가 → invalid ← 안전한 쪽으로 실패 (fail-safe)
|
| 원인 | 예 |
|---|
| 필드가 구현 한도보다 김 | 매우 긴 OCTET STRING |
| 배열 항목이 너무 많음 | 수천 개의 PSID가 든 appPermissions |
| 재귀 구조가 너무 깊게 중첩 | Ieee1609Dot2Data 안에 Ieee1609Dot2Data가 계속 중첩 |
| 인식할 수 없는 식별자 | 모르는 확장 ID, 모르는 PSID |
- 인식할 수 없는 식별자가 있을 때의 처리 (구현 방식에 따라 선택)
- 엄격한 방식 : 인식하지 못하는 식별자가 하나라도 있으면 invalid
- 유연한 방식 : 검증에 필요한 식별자만 인식하면 나머지는 무시하고, 필요한 식별자를 인식하지 못한 경우에만 invalid
ASN.1 확장 마커(...) 덕분에 구버전 구현도 새 필드를 디코딩할 수는 있다. 하지만 디코딩할 수 있다는 것과 의미를 이해했다는 것은 다르다. 이 조건은 그 차이를 다룬다.
10. 보안 프로파일 (Security Profile)
- SDEE 명세 작성자(SDEE specifier)가 어떤 SDS 파라미터를 사용하고 각 파라미터에 어떤 값을 설정할지를 간결하게 명시하기 위한 형식
- 명세마다 표현 방식이 달라지지 않도록 일관성을 확보
- 앞에서 나온 “SDEE 명세에서 정한다”는 값들이 모두 여기에 들어간다.
- 자체 서명 허용 여부, 체인 길이 한도, 신선도·거리 임계값, 선택적 일관성 조건 적용 여부 등
| 용어 | 의미 |
|---|
| SDEE specifier | 어떤 보안 서비스를 사용할지 결정하는 주체. 결정은 SPDU가 속한 information flow의 내용과 기능에 따라 달라진다. |
| information flow | 하나 이상의 송신 노드를 포함하여 특정 목적을 달성하기 위해 설계된 데이터 전송 과정 |
| information subflow | information flow 중 단일 송신자에 대응하는 하위 흐름 |
표현 형식
| 열 | 내용 |
|---|
| Name | 보안 속성의 이름 |
| Value | 단일 값, 값 목록, 텍스트 문자열, “n/a” 등 |
| Notes | 값에 대한 보충 설명. 규범적 명세의 일부이며 본문의 다른 위치를 참조할 수 있음 |
| 열 | 내용 |
|---|
| Name | 속성 이름 |
| Type | 속성 유형 (열거형, 열거값 리스트 등) |
| Valid Range | 허용되는 값 범위 |
| Description | 해당 값이 보안 처리에서 어떤 의미를 갖는지 |
예시 (설명용)
- BSM 같은 안전 메시지의 보안 프로파일을 3열 표로 표현하면 대략 다음과 같다.
| Name | Value | Notes |
|---|
| 서명 여부 | 서명함 | 모든 BSM은 signed SPDU |
| 서명자 식별 방식 | digest / certificate | 평소 digest, 주기적으로 certificate |
| generationTime 포함 | 예 | 신선도 검사에 사용 |
| generationLocation 포함 | 아니요 | 위치는 BSM payload에 포함 |
| 자체 서명 허용 | 아니요 | |
| 신선도 허용 기간 | 수백 ms ~ 수 초 | 관련성 조건 |
| 재전송 검사 | 수행 | 관련성 조건 |
속성 이름과 값은 이해를 돕기 위한 예시이며, 실제 값은 해당 SDEE 명세(예: SAE J2945/1)를 따른다.
11. 정리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| signed SPDU 송신
└─ 생성 : payload + headerInfo → tbsData → 정규화·COER → H(H(tbsData) ‖ H(인증서)) → ECDSA 서명
→ SignedData { hashId, tbsData, signer, signature }
signed SPDU 수신
├─ 전처리 : 유형·PSID·시각 등 추출, 처리할지 결정
├─ 서명 검증 : 검증 키 확보 → 해시 재계산 → ECDSA 검증 (PASS = 위·변조 없음)
└─ 유효성 판단
├─ 일관성 (수신자 상태와 무관, SPDU 내용으로 판단)
│ ├─ 전역 : 형식, 서명, 체인, 폐기 상태, PSID/생성 시각/지역 ↔ 인증서, 시각 순서, 확장
│ ├─ SDEE별 : (SDS) PSID 문맥, 체인 길이 / (SDEE) payload 권한, 외부 데이터 해시, 영역, appExtensions
│ └─ Payload : Asserted data, 지리 정보 유형
├─ 관련성 (수신자 로컬 상태로 판단)
│ └─ 신선도, 미래 생성, 만료, 위치, 재전송, 인증서 만료
└─ 핵심 필드 해석 가능 여부
↓
임계값·선택 조건은 모두 "보안 프로파일"에서 정의
|