제9부 규격·프로토콜·인터페이스
9.5 MAVLink: 메시지 구조·마이크로서비스·서명과 보안 한계
9.5.1 이 장에서 배우는 것 / 선수 지식 / 특히 중요한 독자
MAVLink는 소형 무인기의 오토파일럿, 지상통제소(GCS), 임무 컴퓨터, 짐벌·카메라가 메시지를 주고받는 경량 오픈 프로토콜이다. 이 장은 규격을 두 층으로 읽는다. 프레임 층은 메시지 하나를 바이트열로 만드는 규칙이다. 서비스 층은 여러 메시지의 순서·타이머·재시도를 정하는 마이크로서비스다. 두 층 어디에도 암호화는 없고, 인증(서명)은 선택 사항이다. 이 장은 그 한계를 원문과 계산으로 확인한다.
배우는 것:
- 프레임 — v1·v2 패킷 형식, 필드 재배열, 확장 필드와 0 절단, CRC-16과 CRC_EXTRA.
- 정의 파일과 식별 — minimal·standard·common, 메시지 ID 공간, 시스템·구성요소 ID, 라우팅.
- 마이크로서비스 — 하트비트, 명령, 파라미터, 임무, 고지연 링크의 절차와 타이머.
- 서명 — 13바이트 구조, 타임스탬프 규칙, 키 설정, C 라이브러리·PX4·ArduPilot의 차이.
- 세 가지 계산 — 바이트 단위 패킷 재현과 링크 점유율, 48비트 서명의 위조 확률과 키 도출, 임무 업로드 시간과 손실에서의 중단 확률.
- 보안 한계 — 평문, 선택성, 공유 키 하나, 회전 부재, 비서명 허용 목록, v1 채널.
선수 지식: 2.10(비행 소프트웨어 구조와 현장 갱신), 2.11(지상통제소), 3.11(C2 링크의 생존 신호와 링크 상실), 3.18.3(링크 보안의 비용), 8.11.7(태그 길이 계산), 9.1.2(사실상 표준)를 읽었다고 가정한다. 내부 버스는 9.4가, 오토파일럿 생태계와 ROS 2는 9.6이, 암호·키 관리 규격은 9.19가, 하이재킹 대응은 8.16이 다룬다.
특히 중요한 독자: 엔지니어는 9.5.3~9.5.9를, 보안·인증 담당자는 9.5.6·9.5.8·9.5.10·9.5.11을, 정책 담당자는 9.5.10·9.5.12·9.5.14를, 운영·사업 담당자는 9.5.11과 9.5.15를 먼저 읽는다.
기준 시점과 정직성. 2026년 11월 기준이다. 원문을 읽은 것: mavlink.io 개발자 가이드의 원본 마크다운(mavlink-devguide 커밋 226d443, 2026-10-29)에서 직렬화·MAVLink 2·서명·라우팅·버전·XML 스키마·메시지 정의 작성·CRC·메시지율·중복 제거·패킷 손실 가이드, 서비스 중 하트비트·명령·파라미터·임무·고지연·ID 할당·핑·시각 동기·암 승인·FTP·터널·Open Drone ID·오프보드 제어·수동 조종(앞부분의 절차·개요). XML 정의(mavlink 커밋 6bf60db, 2026-10-28)의 minimal·standard·common·all. C 라이브러리 c_library_v2(커밋 a2d0ecf, 2026-10-28)의 checksum.h·mavlink_helpers.h·mavlink_types.h와 pymavlink 생성기(커밋 03af8c2)의 mavparse.py·mavcrc.py. 서명 제안서(구글 문서 내보내기). PX4 서명 문서(PX4-Autopilot
main, 커밋 36919f8, 2026-10-31)와 ArduPilot의 MAVLink2 Signing·Security 페이지. IETF RFC 2104 5절, RFC 8439 4절, RFC 9147 4.5.3절. 학술 논문 2편(MAVSec 2019, Kwon 외 2018). 직접 확인한 것: c_library_v2를 gcc로 컴파일해 얻은 패킷 8개(서명 2개 포함)와 이 장의 계산이 바이트 단위로 일치하고, 17개 메시지의 CRC_EXTRA·페이로드 길이가 C 라이브러리의 표와 일치한다. 읽지 못한 것: Marty(2014, AFIT 석사 논문)는 사이트가 접근을 차단해(403) 받지 못했고 검색 요약으로만 안다(미확인). MAVLink 2 설계 문서(구글 문서), 카메라·짐벌·컴포넌트 메타데이터·이벤트 서비스의 본문, PX4·ArduPilot의 서명 구현 소스, QGroundControl·MAVSDK의 동작. PX4 문서는 개발판(main)이라 배포판과 다를 수 있고 ArduPilot 페이지는 날짜를 확인하지 못했다(확인 필요). 2차 문헌은(2차 출처)로 표시한다.
9.5.2 개념·직관 — 프레임과 서비스, 그리고 정하지 않은 것
MAVLink가 정하는 것은 셋이다. 메시지의 바이트 배치와 오류 검출(프레임), 메시지의 식별과 주소(메시지 ID, 시스템 ID, 구성요소 ID), 여러 메시지로 이루어진 절차(마이크로서비스)다. 서비스는 대부분 클라이언트–서버 형태이고 지상통제소가 요청하면 기체가 응답한다(서비스 색인의 서술).
MAVLink가 정하지 않는 것도 분명하다. 전송 매체(직렬 무선, UDP 등)는 정하지 않는다. 하트비트 주기와 단절 판정은 링크마다 정한다(원문: "not defined by MAVLink"). 암호화, 키 배포·회전, 역할별 접근 통제도 없다. 그래서 MAVLink의 보안은 두 곳에서 결정된다. 하나는 프로토콜이 제공하는 선택 기능인 서명이고, 다른 하나는 프로토콜 바깥의 링크·운용 정책이다. ArduPilot의 보안 페이지는 이 경계를 직접 적는다. 보안 경계는 물리 통신 인터페이스(무선 링크, 네트워크 케이블, USB 케이블)까지이고 그 너머의 C2 링크와 기체 내부 네트워크의 보안은 사용자 책임이다.
세 축에서의 위치는 다르다. 민간 UAS에서는 PX4·ArduPilot 계열과 QGroundControl이 공유하는 사실상 표준이다(9.1.2의 구분). 군용 체계의 상호운용 규격은 이 장의 범위 밖이다(9.7). AAM의 인증 대상 C2 링크는 별도의 성능·감항 보안 요구(8.11·9.13)를 만족해야 하며, MAVLink를 그 입증 근거로 사용할 수 있는지는 이 장의 자료로 답할 수 없다 (확인 필요).
9.5.3 패킷 구조 — v1과 v2 프레임
원문은 프레임 형식이 CAN과 SAE AS-4 표준에서 영감을 얻었다고 밝히고, 다바이트 필드를 모두 리틀 엔디언으로 직렬화한다. 시작 바이트가 다르면(v1은 0xFE, v2는 0xFD) 해당 버전을 모르는 라이브러리는 패킷을 인식하지 못하고 건너뛴다. 그림 1은 v2 서명 패킷의 배치와 두 계산의 입력 범위를 보인다.
| 항목 | MAVLink 1 | MAVLink 2 |
|---|---|---|
| 시작 표지·헤더 | 0xFE, 6바이트 | 0xFD, 10바이트 |
| 메시지 ID | 8비트(0~255) | 24비트(0~16,777,215) |
| 페이로드 | 0~255바이트, 항상 전부 전송 | 0~255바이트, 끝의 0 바이트를 잘라 낸다 |
| 확장 필드 | 전송하지 않는다 | 전송한다(재배열·CRC_EXTRA에서 제외) |
| 플래그 | 없음 | 비호환·호환 플래그 각 1바이트 |
| 서명 | 없음 | 선택 13바이트 |
| 최소·최대 길이 | 8·263바이트 | 12·280바이트 |
| 채택 시기(원문) | 2013년경 널리 채택 | 2017년 초 주요 사용자 채택 |
플래그. 비호환 플래그를 이해하지 못하는 구현은 패킷을 반드시 폐기해야 한다. 원문 작성 시점에 정의된 비호환 플래그는 서명(0x01) 하나다. 호환 플래그는 모르면 무시해도 된다. 그래서 서명을 지원하지 않는 v2 라이브러리는 서명된 패킷을 모두 버린다.
버전 확인. 시작 표지, 또는 AUTOPILOT_VERSION의 MAV_PROTOCOL_CAPABILITY_MAVLINK2 비트로 알 수 있다. 라우터가 패킷을 다시 직렬화하거나 고정 길이 패킷화 무선이 가변 길이 v2 프레임을 왜곡·절단하면 링크가 투명하지 않다(원문: 구형 SiK 무선이 v2 메시지를 소비할 수 있다). 확인하려면 ID 256 초과 메시지를 MAV_CMD_REQUEST_MESSAGE로 요청해 v2 프레임으로 응답이 오는지 본다. 서명이 켜져 있으면 기체는 시작 때부터 서명된 v2를 보낸다.
필드 재배열. 전송 순서는 XML 선언 순서가 아니다. 필드를 형의 크기 순(8·4·2·1바이트)으로 안정 정렬하며, 배열은 원소 크기로 정렬한다. 확장 필드는 XML 순서대로 끝에 붙고 재배열 대상이 아니다. 이 규칙은 정렬 맞춤 문제를 피하려는 것이다.
0 절단. v2는 페이로드 끝의 0 바이트를 반드시 제거하고 len에 반영한다. 첫 바이트는 전부 0이어도 남긴다. 확장 필드는 대개 0이므로 가장 먼저 잘리고, 송신 측이 신규 필드를 추가해도 구형 수신 측은 그 필드를 보지 못한다. 반대로 구형 송신 측이 보낸 패킷에서 신규 필드는 0으로 읽힌다.
체크섬과 CRC_EXTRA. 체크섬은 CRC-16/MCRF4XX(초기값 0xFFFF)이고 입력은 시작 표지를 뺀 헤더, 페이로드, 그리고 마지막에 더하는 CRC_EXTRA 한 바이트다. 서명은 입력이 아니다. CRC_EXTRA는 전송되지 않는다. 송수신 양쪽이 같은 메시지 정의에서 계산한 지문으로, 정의가 다르면 체크섬이 어긋나 패킷이 버려진다.
$$\mathrm{CRC\_EXTRA}=(c \bmod 256)\oplus\left\lfloor c/256\right\rfloor,\qquad c=\mathrm{CRC16}(s)$$
여기서 $s$는 메시지 이름과, 전송 순서로 늘어놓은 기본 필드의 형·이름(배열이면 길이 1바이트)을 공백으로 이은 문자열이다. 확장 필드는 $s$에 들어가지 않는다. CRC와 CRC_EXTRA는 공개 정의에서 누구나 계산하므로 오류 검출이며 인증이 아니다.
9.5.4 정의 파일·ID 공간·라우팅
정의 파일과 방언. 메시지는 XML로 정의하고 생성기가 언어별 코드를 만든다. 세 층이 include로 이어진다(색인 문서의 서술). minimal.xml은 네트워크를 구성하는 데 필요한 최소 항목(HEARTBEAT 등)이다. standard.xml은 핵심 비행 스택 둘 이상이 호환되게 구현한 항목이고, common.xml은 적어도 하나의 핵심 스택이 구현한 항목이다. 방언(dialect)은 common.xml을 포함하고 자기 항목만 더한다. development.xml과 wip 표지가 붙은 항목은 개발 중이므로 배포 소프트웨어에서 사용하면 안 된다.
이 장이 읽은 XML(커밋 6bf60db)에서 common.xml은 minimal·standard를 포함해 235개 메시지를 가진다. 142개는 ID가 255 이하이고 93개는 256 이상이어서 MAVLink 1로는 전송할 수 없다. 76개 메시지가 확장 필드를 가진다. 정의는 바뀐다. MISSION_ITEM·MISSION_REQUEST는 2020-06에 폐기되고(대체: _INT 형), MISSION_SET_CURRENT는 2022-08에 명령으로 대체되었으며, TRAJECTORY_REPRESENTATION_WAYPOINTS·BEZIER는 2025-03에 대체 없이 폐기되었다.
| 정의 | 메시지 ID 범위 | 명령 ID 범위 |
|---|---|---|
| common.xml | 300~10000(v1 시절의 0~255 항목 포함) | 0~39999 |
| ardupilotmega.xml | 11000~11999 | 42000~42999 |
| ASLUAV.xml | 8000~8999 | 40001~41999 |
| uAvionix.xml | 10001~10049 | 미정 |
| loweheiser.xml | 10150~10199 | 10150~10199 |
| icarous.xml | 42000~42999 | 미정 |
| storm32.xml·AVSSUAS.xml | 60000~60049·60050~60099 | 같은 범위 |
범위는 all.xml의 주석에 사람이 관리하는 표다. 생성기는 중복 ID·중복 필드 이름·필드 없는 메시지·필드 64개 초과를 검사하지만 과대 페이로드는 검사하지 않는다(원문). 이 장이 읽은 235개 중 페이로드가 255바이트를 넘는 것은 없고 가장 큰 것은 ENCAPSULATED_DATA(ID 131)의 255바이트다.
정의 변경 규칙. 메시지 이름·ID의 변경과 필드의 추가·삭제·형 변경은 구형 생성 라이브러리와 비호환이다. 확장 필드만 기존 메시지에 필드를 호환되게 추가한다. 메시지는 v1 하드웨어 때문에 거의 삭제되지 않으며, common.xml의 변경에는 주요 이해관계자의 합의가 필요하다(원문). 설명 문구는 바이너리 호환을 깨지 않고 바꿀 수 있다.
식별과 라우팅. 시스템 ID와 구성요소 ID는 모두 1~255이고 프로토콜이 자동 할당하지 않는다. 통합자가 수동으로 정한다. 관례는 오토파일럿이 1부터 증가하고 지상통제소·SDK가 255 쪽에서 감소하는 것이다. 따라서 한 망의 시스템은 255개를 넘을 수 없고, 지상통제소·SDK도 이 공간을 함께 사용한다(7.9이 지적한 식별 수의 한계). 구성요소 ID로 장치 종류를 추정하면 안 되고 HEARTBEAT.type으로 판별한다. 메시지 안의 target_system·target_component가 0이거나 없으면 방송이다. 라우터는 방송을 아직 보지 못한 모든 채널에 전달하고, 주소가 있는 메시지는 그 수신자의 메시지를 이전에 본 채널에만 전달한다. 전달할 때 메시지를 고치면 안 되고, 서명 패킷도 변경 없이 전달해야 한다. 원문은 인증할 수 없는 메시지도 전달 규칙에 따라 전달하라고 한다.
9.5.5 마이크로서비스 — 절차와 타이머
| 서비스 | 메시지 | 절차와 타이머(원문) | 설계상 유의 |
|---|---|---|---|
| 하트비트·연결 | HEARTBEAT | 방송으로 존재·종류·모드를 알린다. RF 링크에서는 1 Hz이고 4~5회 미수신이면 단절로 본다(전형값, MAVLink가 정하지 않는다) | 오류 상태에서는 하트비트를 보내지 않는다. 별도 스레드에서 보내면 안 된다 |
| 명령 | COMMAND_INT·COMMAND_LONG·COMMAND_ACK | ACK가 없으면 자동 재전송한다. LONG은 confirmation을 올려 재전송한다. 장기 명령은 IN_PROGRESS와 진행률(0~100)로 보고한다 | 재전송이 중복 수신되므로 명령은 멱등하게 설계한다(이미 무장이면 ACCEPTED) |
| 파라미터 | PARAM_REQUEST_LIST·READ, PARAM_SET, PARAM_VALUE | 전체 읽기는 기체가 PARAM_VALUE를 하나씩 방송하되 링크 대역의 30~50 % 정도만 사용하도록 사이를 둔다(원문: 합리적). 설정(PARAM_SET)은 실패해도 현재값을 방송한다 | 이름 16자, 값은 float 필드에 넣는다(바이트 인코딩 또는 C 캐스트, 후자는 정수 24비트 정밀도) |
| 임무 | MISSION_COUNT·REQUEST_INT·ITEM_INT·ACK | 항목마다 요청–응답. 타임아웃 권고 기본 1,500 ms·계획 항목 250 ms, 재시도 최대 5회. 순서가 어긋나면 재요청 | 임무·지오펜스·랠리 3종, opaque_id로 변경을 검출해 불필요한 전송을 피한다 |
| 고지연 | HIGH_LATENCY2, MAV_CMD_CONTROL_HIGH_LATENCY | 위성 링크에서는 임무·파라미터를 전송하지 않고 하트비트도 보내지 않는다 | 하트비트가 없으므로 라우팅 표가 만들어지지 않고 직접 연결된 지상통제소만 명령할 수 있다 |
| 암 승인 | MAV_CMD_ARM_AUTHORIZATION_REQUEST | 외부 승인자가 허가·거부(허가의 유효 시간 초 포함)를 ACK로 돌려준다. NASA UTM 준수를 위해 도입 | 승인자의 진위는 링크 인증에 달려 있다(이 책의 해석) |
| 파일 전송(FTP) | FILE_TRANSFER_PROTOCOL | 읽기·기록·삭제·생성, 디렉터리 목록·삭제. ACK·NAK 타임아웃 50 ms | 기록·삭제가 가능하다. 체크섬의 CRC-16과 별개인 MAVLink CRC32를 이 서비스가 사용한다 |
| Remote ID | OPEN_DRONE_ID_* | ASTM F3411·ASD-STAN prEN 4709-002와 호환되는 메시지 | 규격 본문은 읽지 못했다(9.12) |
이 밖에 핑, 시각 동기(TIMESYNC), 터널(원문이 사용을 강하게 말린다), 오프보드 제어, 수동 조종(MANUAL_CONTROL), 카메라·짐벌이 있다. 메시지율은 MAV_CMD_SET_MESSAGE_INTERVAL로 링크별로 조정한다(−1이 비활성, 0이 기본값). 여러 링크로 같은 메시지가 도착해도 중복을 제거하는 장치가 프로토콜에 없다. 순번이 채널마다 독립이기 때문이며, 명령이 멱등해야 하는 이유다.
임무 업로드의 흐름은 그림 2와 같다. 원문의 요점은 셋이다. 새 임무는 완전히 수락된 뒤에야 옛 임무를 대체한다. 오류는 복구 불가이고 기체의 임무는 바뀌지 않는다. 타임아웃은 오류가 아니다.
9.5.6 서명 — 구조·규칙·구현
9.5.6.1 프레임과 계산
서명을 켜면 비호환 플래그의 0x01 비트가 1로 설정되고 13바이트가 붙는다. 링크 ID 8비트, 타임스탬프 48비트, 서명 48비트다. 서명은 비밀 키와 패킷을 이어 붙인 SHA-256의 앞 48비트이며, HMAC이 아니다.
$$\text{서명}=\mathrm{SHA256}(K\,\Vert\,H\,\Vert\,P\,\Vert\,C\,\Vert\,L\,\Vert\,T)_{[0:48]}$$
| 기호 | 뜻 |
|---|---|
| $K$ | 비밀 키 32바이트 |
| $H$, $P$ | 헤더 10바이트, 페이로드(절단 후) |
| $C$ | 체크섬 2바이트 |
| $L$, $T$ | 링크 ID 1바이트, 타임스탬프 6바이트 |
C 라이브러리의 mavlink_sign_packet()이 이 순서로 해시하고 앞 6바이트를 취한다(소스 확인). 타임스탬프는 10 µs 단위, 2015-01-01 UTC 기준이고 UNIX 시각과의 차는 1,420,070,400초다. 한 (시스템 ID, 구성요소 ID, 링크 ID) 흐름에서 단조 증가해야 하며, 패킷율이 평균 10만/s를 넘으면 실제 시각보다 앞선다. 링크 ID는 채널마다 달리 붙여 지연 차가 큰 다중 링크에서 재생 검사가 오동작하지 않게 한다.
9.5.6.2 수락 규칙
수신 측은 서명이 있는 패킷을 셋 중 하나에 해당하면 폐기한다. 같은 흐름의 이전 패킷보다 타임스탬프가 오래되었거나, 계산한 48비트가 일치하지 않거나, 타임스탬프가 로컬 시각보다 1분(6,000,000틱) 넘게 뒤처졌을 때다. 이전 패킷이 없는 새 흐름은 1분 이내이면 수락한다. 로컬 시각 갱신은 올바르게 서명된 패킷의 타임스탬프로만 하며, 틀린 서명을 수락하는 모드에서도 갱신하지 않는다. 부팅 시 시각은 저장한 타임스탬프와 시스템 시계 중 큰 값을 사용하고, 저장은 가능하면 1분에 한 번 이상이다.
비서명 패킷의 수락은 구현이 정한다. 원문의 예는 파라미터 설정, USB·유선 이더넷 같은 안전한 채널, RADIO_STATUS 상시 수락, 부팅 시 버튼 모드, 첫 서명 패킷 수신까지 수락이다. 이 규칙에 맞지 않는 패킷을 모두 거부하지 않으면 서명의 이득이 없다고 원문이 적는다. 틀린 서명의 패킷도 조건부로 수락할 수 있다(분실 기체의 위치 확인 용도). 이때 연결이 안전하지 않음을 눈에 띄게 표시해야 한다.
9.5.6.3 키와 구현
키는 32바이트이고 지상통제소가 만들어 USB·유선 이더넷 같은 보안 링크로 SETUP_SIGNING(ID 256) 메시지에 실어 배포하라는 것이 권고다. 방송하거나 자동 전달하면 안 된다. 키는 파라미터·로그에 나타나면 안 되고, 로그에는 서명 블록을 제거하고 기록하라고 한다(오프라인 공격 방지). 키 생성은 구현 몫이며 원문은 사용자 문자열의 SHA-256과 난수 생성기를 예로 든다. 모든 값이 0인 키와 타임스탬프를 보내면 서명이 해제된다(XML 정의). C·Python 라이브러리는 링크당 키 하나만 지원하지만 이는 라이브러리의 선택이다. 한 채널에는 서명 v2, 비서명 v2, v1을 섞을 수 없다. 원문은 현재 대부분의 망이 서명 없는 v2를 사용한다고 적는다.
| 항목 | 규격(가이드) | PX4(문서) | ArduPilot(문서) |
|---|---|---|---|
| 키 보관 | 지속 저장소 | SD 카드 40바이트 파일(키 32 + 타임스탬프 8, 권한 0600) | 문서에 없음 (확인 필요) |
| 적용 범위 | 채널(링크)별 | 키가 있으면 USB 포함 모든 링크 | v2 직렬 포트만. USB와 v1 포트는 보호되지 않음 |
| 비서명 수락 | 구현이 정함 | HEARTBEAT·RADIO_STATUS는 모든 링크, ADSB_VEHICLE·COLLISION은 교통 수신기 링크 | 서명 없는 패킷의 명령에 응답하지 않음. 다운링크 텔레메트리는 영향 없음 |
| 키 변경 | SETUP_SIGNING | 키가 없으면 어느 링크든 첫 메시지 수락, 이후 현재 키로 서명한 메시지만, 무장 중 거부 | 지상통제소 도구에서 키 목록 관리, USB로 해제·변경 |
| 키 분실 | 규정 없음 | 소프트웨어 복구 경로 없음(의도적). SD 카드 삭제 또는 SWD 재기록 | USB로 해제 가능 |
C 라이브러리의 검증은 서명 비교, 흐름 조회, 새 흐름의 60초 규칙, 재생 검사 순서이며 상태 코드는 일곱 가지(없음·정상·서명 불량·흐름 없음·흐름 과다·타임스탬프 오래됨·재생)다. 기본 설정은 흐름 16개(MAVLINK_MAX_SIGNING_STREAMS)까지만 추적하고 그 이상의 새 흐름은 거부한다(재정의 가능). 서명 비교는 memcmp다. 구조체 주석은 타임스탬프를 UNIX 기준 마이크로초라 적지만 코드의 60초 상수(60 * 100000)와 가이드는 10 µs 단위다.
9.5.7 워크스루 I — 패킷 해부·CRC_EXTRA·링크 점유율
9.5.7.1 HEARTBEAT 21바이트
c_library_v2가 만든 HEARTBEAT(시스템 1, 구성요소 1, 쿼드로터·PX4·STANDBY)를 같은 규칙으로 직렬화해 21바이트가 일치함을 확인했다(9.5-calc.py).
| 바이트 | 값(16진) | 뜻 |
|---|---|---|
| 0 | FD | v2 시작 표지 |
| 1~3 | 09 00 00 | 페이로드 9바이트, 플래그 없음 |
| 4~6 | 00 01 01 | 순번 0, 시스템 1, 구성요소 1 |
| 7~9 | 00 00 00 | 메시지 ID 0 |
| 10~13 | 00 00 00 00 | custom_mode(32비트라서 XML 순서와 달리 맨 앞) |
| 14~18 | 02 0C 51 03 03 | 종류 쿼드로터(2), 오토파일럿 PX4(12), 모드 81, 상태 STANDBY(3), mavlink_version 3 |
| 19~20 | 1E F8 | CRC 0xF81E(리틀 엔디언) |
CRC_EXTRA(50)를 더하지 않으면 같은 입력의 CRC는 0xE93D로 달라진다. CRC의 한 바이트 단계는 단사여서 256가지 마지막 바이트가 256개의 서로 다른 CRC를 만든다(계산). 따라서 CRC_EXTRA가 다르면 체크섬은 반드시 달라진다.
9.5.7.2 CRC_EXTRA의 정의 지문과 한계
임베드한 정의로 계산한 CRC_EXTRA가 C 라이브러리 표와 17개 메시지 모두 일치한다.
| 메시지(ID) | 페이로드 기본/확장 포함 [B] | CRC_EXTRA |
|---|---|---|
| HEARTBEAT(0) | 9 / 9 | 50 |
| SYS_STATUS(1) | 31 / 43 | 124 |
| ATTITUDE(30) | 28 / 28 | 39 |
| GLOBAL_POSITION_INT(33) | 28 / 28 | 104 |
| MISSION_REQUEST_INT(51) | 4 / 5 | 196 |
| MISSION_ITEM_INT(73) | 37 / 38 | 38 |
| COMMAND_LONG(76) | 33 / 33 | 152 |
| SETUP_SIGNING(256) | 42 / 42 | 71 |
CRC_EXTRA는 8비트이므로 호환되지 않는 정의가 같은 값을 가질 수 있다. common.xml 235개 메시지에서 기본 필드 하나의 이름을 바꾸거나 필드 하나를 추가한 변형 1,994개를 만들어 보니 12개(0.60 %)가 CRC_EXTRA가 그대로였다(이론값 1/256 = 0.39 %, 기대 7.8개). 서로 다른 값은 235개 메시지 중 162가지다. 정의 불일치의 대부분은 걸러지지만 전부는 아니므로 호환성은 CRC가 아니라 버전 관리와 시험이 보장해야 한다.
9.5.7.3 절단과 패킷 크기
v2의 절단은 실제로 일어난다. MISSION_REQUEST_INT는 확장 필드 mission_type이 0이면 5바이트가 4바이트로 줄고, COMMAND_LONG(무장)은 confirmation이 0이어서 33바이트가 32바이트로, MISSION_ITEM_INT는 38바이트가 37바이트로 준다. 서명 13바이트가 크기에 주는 영향은 짧은 메시지일수록 크다.
| 메시지 | 페이로드 [B] | v1 | v2 | v2 서명 | 서명 증가율(v2 대비) |
|---|---|---|---|---|---|
| HEARTBEAT | 9 | 17 | 21 | 34 | +61.9 % |
| ATTITUDE | 28 | 36 | 40 | 53 | +32.5 % |
| PARAM_VALUE | 25 | 33 | 37 | 50 | +35.1 % |
| COMMAND_LONG(무장) | 32 | 40 | 44 | 57 | +29.5 % |
| MISSION_ITEM_INT | 37 | 45 | 49 | 62 | +26.5 % |
| SETUP_SIGNING·HIGH_LATENCY2 | 42 | 50 | 54 | 67 | +24.1 % |
HIGH_LATENCY2는 서명을 붙이면 54바이트가 67바이트가 되어 고지연 링크의 메시지당 비용에 직접 반영된다. SETUP_SIGNING은 키 32바이트를 평문 페이로드로 싣는 메시지다.
9.5.7.4 직렬 링크의 점유율
대표 텔레메트리 묶음을 가정한다. HEARTBEAT 1 Hz, SYS_STATUS·GPS_RAW_INT·VFR_HUD 각 2 Hz, ATTITUDE 10 Hz, GLOBAL_POSITION_INT 5 Hz로 합 22패킷/s이고, 페이로드는 기본 필드 길이(확장 필드는 0으로 절단)를 사용하며 직렬은 8N1(바이트당 10비트)이다. 데이터율은 v1이 767 B/s, v2가 855 B/s(6.84 kbit/s), 서명 v2가 1,141 B/s(9.13 kbit/s)다.
그림 3은 링크 속도에 따른 묶음의 점유율이다.
57.6k baud에서 묶음은 v1이 13.3 %, v2가 14.8 %, 서명 v2가 19.8 %를 차지해 서명 비용은 5.0 %p다. 9.6k baud에서는 v2가 89.1 %, 서명 v2가 118.9 %여서 서명을 붙이면 링크 용량을 넘는다. 메시지율을 낮추거나 링크를 올려야 한다. ATTITUDE 단독 최대율은 57.6k baud에서 v1 160.0 Hz, v2 144.0 Hz, 서명 v2 108.7 Hz다. 3.18.9의 인증 비용 계산(40바이트에 13바이트, 약 +33 %)과 같은 구조이며, 여기서는 실제 메시지 크기를 사용했다.
9.5.8 워크스루 II — 서명의 안전 여유
9.5.8.1 48비트 태그의 위조 확률
공격자가 키를 모른 채 임의의 태그를 시도하면 한 번에 $2^{-48}$로 수락된다. 시도가 $n$번이면 $P=1-(1-2^{-48})^{n}$이다. 8.11.7의 식과 같고, 이 장은 그 계산을 다시 구현해 최소 태그 길이 50·54·56비트가 재현됨을 확인한 뒤 태그 길이를 MAVLink의 48비트로 고정했다. 공격자의 시도율은 링크 용량이 정하고, 링크 전체를 위조 프레임으로 채운다고 가정한다(가정). 목표 $10^{-9}$은 DO-356A의 위협 수준이 아니라 8.11.7의 설명용 가정이다.
| 링크(8.11.7 가정) | 시간당 시도 | P(1시간) | 첫 수락까지의 기대 시간 |
|---|---|---|---|
| 50 kbps·256비트 프레임 | 703,125 | $2.5\times10^{-9}$ | 45,667년 |
| 1 Mbps·256비트 | 14,062,500 | $5.0\times10^{-8}$ | 2,283년 |
| 10 Mbps·512비트 | 70,312,500 | $2.5\times10^{-7}$ | 457년 |
세 링크 모두 1시간 P가 $10^{-9}$을 넘는다. 48비트 태그가 $10^{-9}$을 만족하려면 키 수명 동안 누적 시도가 281,475회 이하여야 한다. 50 kbps에서 위조 프레임을 연속으로 보내면 24.0분이다. 키를 바꾸지 않으면 누적된다. 같은 링크에서 1일 $6.0\times10^{-8}$, 30일 $1.8\times10^{-6}$, 1년 $2.2\times10^{-5}$다. 이 수치만으로 안전 여부가 결정되지는 않는다. 계산은 시도 한 번이 독립이고 수락 확률이 정확히 $2^{-48}$이라는 가정을 따른다. 한편 수락된 시도는 공격자가 고른 내용(원하는 명령)을 포함할 수 있어 위험의 크기를 키운다.
같은 50 kbps에서 태그가 64비트이면 $3.8\times10^{-14}$, 80비트이면 $5.8\times10^{-19}$, 128비트이면 $2.1\times10^{-33}$이다. 기준 문서는 이 길이를 다르게 본다. RFC 2104 5절은 HMAC의 절단을 해시 출력의 절반(SHA-256이면 128비트)과 80비트 이상으로 권고하고, RFC 8439 4절은 ChaCha20-Poly1305에서 태그 절단을 금지한다. 둘 다 MAVLink의 구성(비밀 키 접두 SHA-256)에 직접 적용되는 문서가 아니므로 비교 기준일 뿐이다.
검증 비용. 위조 프레임도 수신 측이 SHA-256을 한 번 계산해야 거부할 수 있다. 제안서는 Pixhawk1에서 패킷당 평균 26 µs(최악 28 µs), 코드 812바이트, 스택 약 500바이트를 측정했다(2015년경). 초당 195개(50 kbps)는 CPU의 0.5 %, 3,906개(1 Mbps)는 10.2 %, 19,531개(10 Mbps)는 50.8 %다. 이더넷·UDP로 노출된 링크에서는 서명 검증 자체가 서비스 거부의 표적이 될 수 있다. 현재 MCU는 더 빠르거나 해시 가속기가 있으므로 이 값은 상한이 아닌 예시다 (추정).
9.5.8.2 타임스탬프와 재생
48비트 타임스탬프는 10 µs 틱에서 약 89.2년이고 2104-03-13에 한 바퀴 돈다. 제안서는 이 프로토콜이 2104년 전에 퇴역한다고 가정한다. 1분 창은 6,000,000틱이다. 제안서 한 곳은 재부팅 한 번이 소비하는 틱을 "6천만"이라 적지만 1분은 600만 틱이므로 같은 문서의 다른 서술과 어긋난다(이 장이 600만으로 바로잡음).
재생 방지는 단조 증가 타임스탬프와 새 흐름의 1분 규칙에 의존한다. PX4 문서는 대부분의 기체가 배터리를 뽑아 끄므로 디스크의 타임스탬프가 마지막 키 설정 시점에 머무는 경우가 많다고 적는다. C 라이브러리의 흐름 표는 구조체로만 정의되고 영구 저장 규정이 없다. 두 사실과 규칙에서 다음 추정이 나온다. 수신 측이 재부팅했고 신뢰할 시계(RTC, GPS 시각)도 아직 없으면 로컬 시각은 낡은 저장값에 머문다. 이때 흐름 표는 비어 있고 새 흐름은 "로컬 시각보다 1분 넘게 뒤처지지 않으면" 수락되므로, 저장값 이후에 캡처된 정당한 서명 패킷이 첫 패킷으로 수락될 수 있다. 정당한 송신자의 더 새로운 패킷이 도착하면 로컬 시각이 올라가 창이 닫힌다. 제안서는 부팅 시 시스템 시계와 저장값 중 큰 값을 사용하라고 권고하므로, 시계가 있는 구현에서는 창이 1분으로 줄어든다 (추정, 구현을 시험하지 않았다).
9.5.8.3 사용자 문자열에서 도출한 키
원문은 사용자가 입력한 문자열에 SHA-256을 적용해 키를 만드는 방식을 허용한다. 서명된 패킷 하나만 있으면 후보 키를 오프라인에서 검증할 수 있다(48비트 태그의 우연 일치 확률은 $2^{-48}$). 후보 검증 속도를 초당 $10^{10}$회로 가정하면 전수 탐색 시간은 다음과 같다.
| 문자열 | 공간 | 전수 탐색 |
|---|---|---|
| 소문자 8자 | $2.1\times10^{11}$(37.6비트) | 20.9초 |
| 영숫자 8자 | $2.2\times10^{14}$(47.6비트) | 6.07시간 |
| 인쇄 가능 ASCII 10자 | $6.0\times10^{19}$(65.7비트) | 190년 |
| 인쇄 가능 ASCII 12자 | $5.4\times10^{23}$(78.8비트) | 171만 년 |
| 난수 32바이트 | $1.2\times10^{77}$ | 해당 없음 |
속도는 측정값이 아닌 자릿수 가정이고, 서명 패킷이 로그에 남으면 이 공격이 가능해지므로 제안서는 로그에서 서명 블록을 제거하라고 권고한다. 키는 난수 생성기로 만드는 것이 타당하다(이 책의 견해).
9.5.9 워크스루 III — 임무 업로드와 파라미터 다운로드
임무 업로드 시간. 항목마다 요청(16바이트)과 항목(49바이트) 한 쌍이 오가므로 57.6k baud에서 직렬화 시간은 항목당 11.28 ms다. 전이중 링크에 왕복 지연 RTT를 더한 단순 모형으로 계산했다.
| 항목 수 $N$ | RTT 50 ms | RTT 200 ms |
|---|---|---|
| 50 | 3.1초 | 10.8초 |
| 100 | 6.2초 | 21.3초 |
| 500 | 30.7초 | 105.8초 |
권고 타임아웃(항목 250 ms)보다 RTT가 길면 첫 응답이 오기 전에 재요청이 나간다. RTT 600 ms이면 항목마다 2회다. 최초 1회와 재시도 5회의 대기를 합한 1.5초 안에 응답이 없으면 취소한다. 원문이 고지연 링크의 예로 드는 이리듐 위성망은 메시지 지연이 1초를 넘으므로 이 절차를 사용하기 어렵다. 고지연 서비스가 임무 전송을 금지하는 이유다. 어느 메시지에 어느 타임아웃을 적용하는지 원문이 문장으로 정하지 않아, 항목 주기에 250 ms를 적용한 것은 해석이다.
손실과 중단. 요청과 항목 중 하나라도 분실되면 기체의 타이머가 만료되어 같은 요청을 다시 보낸다. 메시지 손실 확률을 $p$로 독립이라 가정하면 한 주기의 성공 확률은 $q=(1-p)^2$이고, 6회가 모두 실패할 확률은 $(1-q)^6$, $N$항목 임무의 중단 확률은 $1-\bigl(1-(1-q)^6\bigr)^{N}$이다.
| 손실 $p$ | 항목 중단 확률 | $N=100$ 중단 확률 | 항목당 추가 시간 |
|---|---|---|---|
| 1 % | $6.2\times10^{-11}$ | 거의 0 | 5 ms |
| 5 % | $8.6\times10^{-7}$ | 0.01 % | 27 ms |
| 10 % | $4.7\times10^{-5}$ | 0.47 % | 59 ms |
| 20 % | $2.2\times10^{-3}$ | 19.58 % | 141 ms |
| 30 % | $1.8\times10^{-2}$ | 83.06 % | 260 ms |
손실이 10 %까지는 임무 업로드가 사실상 성공하지만 20 %를 넘으면 큰 임무는 중단되는 경우가 많다. 중단되어도 기체의 기존 임무는 그대로이므로 안전한 방향으로 실패한다. 단 사용자가 중단을 모르고 이륙하면 옛 임무가 실행된다(이 책의 지적). opaque_id 비교와 업로드 결과 확인이 운용 절차에 들어가야 한다.
파라미터 다운로드. PARAM_VALUE는 페이로드 25바이트, v2 패킷 37바이트(서명 시 50바이트)다. 기체 하나가 파라미터 1,000개(가정)를 보낼 때 57.6k baud에서 링크 전부를 사용하면 6.4초(서명 8.7초), 원문 권고의 30~50 %만 사용하면 12.8~21.4초(서명 17.4~28.9초)다. 원문은 파라미터 집합을 하나의 패킹한 파일로 보내면 저대역 링크에서 훨씬 빠르고 안정적이라고 적는다(FTP 기반 서비스).
9.5.10 보안 한계 — 서명이 정하지 않는 것
| 한계 | 근거 | 영향 | 방호의 범주 |
|---|---|---|---|
| 평문 | PX4·ArduPilot 문서: 서명은 인증·무결성만. 도청자는 텔레메트리·명령·파라미터·임무를 읽는다 | 기밀성 없음. 임무·위치가 노출된다 | 링크 계층 암호화(3.18, 9.19) |
| 서명이 선택 | 가이드: 서명 필드는 선택. 대부분의 망이 서명 없는 v2 | 인증 없는 명령 주입(Kwon 2018은 와이파이로 연결한 v1 시험대에서 도청 후 패킷 주입으로 임무를 중단시켰다고 보고) | 서명 활성화, 비서명 수락 최소화 |
| v1 채널 | ArduPilot: v1 직렬 포트는 보호되지 않음. 한 채널에 서명 v2·비서명 v2·v1 혼용 불가 | 구형 주변장치용 채널이 인증 없는 진입점 | 채널 분리, v1 퇴출 |
| 송신자 식별 | 헤더의 sysid·compid는 송신 측이 채우는 값이고 자동 할당·검증 절차가 없다. 목적지 0은 방송이다(라우팅 문서) | 서명이 없으면 누구나 기체·지상통제소로 위장하고, 방송 한 번이 같은 망의 모든 기체에 도달할 수 있다(3.18.3.3의 다기체 경고) | 서명과 링크 계층 인증 |
| 공유 키 하나 | PX4: 키 보유자는 어떤 ID로도 서명한다. 누가 보냈는지가 아니라 키 보유 여부만 인증 | 장치별 폐기·권한 분리 불가. 한 장치 침해가 전체 침해 | 장치별 키는 상위 계층에서(9.19) |
| 키 배포 | SETUP_SIGNING에 키가 평문으로 실린다. 키가 없으면 PX4는 어느 링크든 수락 | 초기 설정 링크가 최약점 | USB 등 신뢰 연결, 방송 금지 |
| 회전·폐기 부재 | PX4: 자동 회전 없음, 수동 재설정. 제안서: 재키 주기는 계산해야 할 과제로 남음 | 48비트 태그의 누적 시도 한계(9.5.8.1)를 키 수명이 정함 | 운용 정책으로 교체 주기 설정(키 계층과 폐기 계산은 8.13.7) |
| 비서명 허용 목록 | PX4: HEARTBEAT·RADIO_STATUS는 모든 링크에서 위조 가능 | 링크 상태·연결 판단을 속일 수 있음(3.11의 생존 신호) | 허용 목록 최소화, 교통 수신기는 전용 링크 |
| 키 저장 | PX4: SD 카드 파일(문서에 암호화 언급 없음). 카드 제거로 서명 해제도 가능 | 노획 시 키 노출·해제(8.17) | 안티탬퍼·키 제로화(8.17) |
| 서비스 거부 | 서명 검증 비용(9.5.8.1), 임무 업로드 중단(9.5.9) | 위조 프레임 흐름과 손실이 서비스를 막는다 | 링크 방호(제5부), 임무 확인 절차 |
| 파일 서비스 | FTP는 기록·삭제 포함. ArduPilot 보안 페이지는 SD 카드와 MAVFtp 보호에 서명을 권고 | 서명이 없으면 파일 서비스도 열린다 | 서비스별 접근 정책 |
| 구현 차이 | 규격은 라우터가 인증 못 해도 전달하라는데 PX4는 서명 없는 메시지를 전달하지 않는다 | 구현마다 보안 동작이 다르다 | 시험으로 확인(9.23) |
공개된 평가와 그 한계. MAVSec(2019)은 MAVLink의 위협을 도청·변조·차단으로 분류하고 ChaCha20 등 암호화를 ArduPilot SITL에 구현해 CPU·메모리를 비교했다. 이 논문은 MAVLink 2 패킷의 최소·최대 길이를 11·297바이트로 적어 이 장이 읽은 원문과 계산(12·280)이 다르다. MAVLink에 인증이 없다고 적은 서술도 있다. Kwon 외(2018)의 실험은 v1 프레임을 와이파이 망으로 주고받는 시험대이고, 공격자가 이미 그 망에 들어와 있다는 가정이다. 둘 다 MAVLink 2 서명 자체의 암호 분석이 아니다. 서명의 독립적 암호 분석은 이번 조사에서 확인하지 못했다 (확인 필요). 이 장의 위조 확률 계산은 모형 계산이지 암호 분석이 아니다.
9.5.11 설계 트레이드오프 — 링크 보안을 어디에 둘 것인가
- ① 서명 없이 격리와 물리 통제에 맡긴다. 오버헤드가 없고 설정이 단순하다. ArduPilot이 말하는 경계(링크 바깥은 사용자 책임)와 같은 입장이다. 단점은 무선·네트워크 링크에서 인증이 전혀 없다는 점이다. 격리 시험장, 유선 기체 내부망, 단거리 교육 기체에 맞다.
- ② MAVLink 2 서명을 켠다. 프로토콜에 내장되어 있고 +13바이트, 검증 26 µs(2015년 Pixhawk1 측정)로 가볍고 PX4·ArduPilot이 지원한다. 단점은 인증만 한다는 점, 공유 키 하나, 회전·폐기 부재, 48비트 태그, 비서명 허용 목록이다. 지상통제소와 기체가 같은 운용자 소유인 소규모 기단에 맞다.
- ③ 하위 계층 보안(DTLS 1.3 같은 데이터그램 터널, 암호화 링크 모뎀)을 두고 서명은 보조로 둔다. 기밀성, 상호 인증, 키 교환과 갱신(KeyUpdate), 128비트 AEAD 태그를 얻는다. RFC 9147 4.5.3절은 DTLS가 인증에 실패한 패킷을 무시하므로 실패 횟수에 한계(GCM·ChaCha20-Poly1305는 $2^{36}$)를 두게 하고, 64비트 태그의 CCM_8은 추가 안전장치 없이 사용하지 못하게 한다. 비용은 크다. DTLS 1.3의 최소 레코드 오버헤드는 통합 헤더 1 + 순번 1 + 내부 형식 1 + 태그 16 = 19바이트로(UDP·IP 헤더 제외) 서명의 13바이트보다 6바이트 크다. UDP가 필요해 직렬 텔레메트리 무선에는 적용할 수 없다. 핸드셰이크와 인증서 운영도 필요하다. 규제 대상 운용, 비가시권 운용, 다기체 기단에 맞는다.
견해: 규제 대상이거나 사람 위 운용의 무선 C2 링크는 ③의 구조(링크 계층의 상호 인증·암호화)를 기본으로 하고 MAVLink 서명은 보조로 둔다. 단거리·소규모 운용은 ②를 최소로 하되 키를 난수 32바이트로 만들고 비서명 허용 목록을 줄인다. 격리 시험 환경만 ①로 충분하다. 근거는 셋이다. 48비트 태그의 누적 시도 한계가 키 수명을 정하는데 MAVLink는 회전을 지원하지 않는다(9.5.8.1). 서명은 평문 노출을 막지 않는다. 비서명 허용 목록이 생존 신호 같은 안전 판단 입력의 위조를 허용한다. 이는 저자의 견해이며, 대안들의 실제 방호 효과는 이 장에서 시험하지 않았다.
9.5.12 세 축 비교
| 항목 | 군용 드론 | 민간 UAS | AAM(eVTOL) |
|---|---|---|---|
| MAVLink의 위치 | 이 장의 범위 밖(상호운용은 9.7, 제19부) | PX4·ArduPilot 계열의 사실상 표준. 지상통제소 소프트웨어와 임무 컴퓨터 인터페이스 | 인증 C2 링크의 근거로 사용할 수 있는지 확인되지 않음 (확인 필요) |
| 인증·암호 | 별도 | 서명은 선택. 기본 활성 여부는 제품별 | 감항 보안 요구(8.11)와 C2 성능 표준(9.13)이 우선 |
| 키 관리 | 별도 | 사람이 키를 설정하고 교체 | 인증 체계의 키 관리(9.19) |
| 링크 가정 | 별도 | 57.6k baud급 직렬 무선에서 Wi-Fi·셀룰러·위성(고지연)까지 | 지상 네트워크와 항공 대역(3.15) |
| 두드러진 위험 | 별도 | 서명 없는 v2 망, v1 주변장치 채널, 키 회전 부재 | 인증 요구와 오픈소스 프로토콜의 입증 간극(9.1.3·9.1.5) |
9.5.13 관련 규격·프로토콜
| 문서 | 발행 | 무엇을 정하나 | 상세 장 |
|---|---|---|---|
| MAVLink 개발자 가이드(직렬화·서명·라우팅·서비스) | MAVLink 프로젝트(오픈소스) | 프레임, CRC_EXTRA, 서명, 서비스 절차 (원문 확인) | 이 장 |
| MAVLink XML 정의(minimal·standard·common·all) | MAVLink 프로젝트 | 메시지·열거형·명령과 ID 범위 (원문 확인) | 이 장 |
| MAVLink 2.0 패킷 서명 제안서 | MAVLink 개발자(2015년경, 2차 출처) | 서명 설계 근거·가정·측정 (원문 확인) | 이 장, 3.18.3 |
| c_library_v2 | MAVLink 프로젝트 | 서명·CRC의 기준 구현 (소스 확인, 컴파일 확인) | 이 장 |
| PX4 MAVLink Message Signing | PX4 프로젝트 | PX4의 서명 구현·한계 (원문 확인, main 문서) | 9.6 |
| ArduPilot MAVLink2 Signing·Security | ArduPilot 프로젝트 | ArduPilot의 서명·보안 경계 (원문 확인, 날짜 확인 필요) | 9.6 |
| RFC 2104(HMAC)·RFC 8439·RFC 9147(DTLS 1.3) | IETF | 비교 기준: 태그 절단, AEAD 태그, 실패 한계 (원문 확인) | 9.19 |
| ASTM F3411·ASD-STAN prEN 4709-002 | ASTM·ASD-STAN | Remote ID. MAVLink 메시지가 호환을 주장 (규격 본문은 읽지 못함) | 9.12, 2.13 |
| DroneCAN(UAVCAN) 연동 지침 | MAVLink 프로젝트 | MAVLink와 CAN 노드의 정보 교환 (가이드 일부 확인) | 9.4 |
| DO-326A·DO-356A·AMC 20-42 | RTCA·EUROCAE·EASA | 인증 제품의 감항 보안 (이 장에서는 읽지 못함) | 8.11 |
9.5.14 관련 규제·인증 요구와의 연결
- 감항 보안(8.11). 인증 제품의 C2 명령 인증은 위협 수준에서 정해진다. 이 장은 8.11.7의 설명용 목표 $10^{-9}$과 48비트 태그를 비교해, 링크 용량에 따라 1시간 P가 목표를 넘는 것을 보였다. MAVLink 서명이 감항 보안을 만족하는지는 이 장이 판단하지 않는다.
- 제품 보안 규제(8.13). CRA 부속서 I는 보안 기본 설정과 명령·설정의 무결성 보호를 요구한다(8.13.4). 서명을 기본 비활성으로 출하하는 제품은 그 선택의 정당화가 필요할 수 있다
(해석, 법률 검토 필요). 서명 키 계층과 폐기 계산은 8.13.7이 다룬다. - 기단 사이버 운영(8.15). C 라이브러리의 서명 상태 코드(서명 불량·타임스탬프 오래됨·재생)는 관제 지표로 사용할 수 있다. 인증 실패 횟수의 증가를 감시하는 것은 8.15.4의 탐지 전략에 연결된다.
- 하이재킹(8.16)·노획(8.17). 링크 주입·재생·허용 목록 위조는 하이재킹의 경로이고, SD 카드 파일에 저장된 키는 노획 시 노출 문제가 있다(문서에 암호화 언급 없음). 대응은 두 장이 다룬다.
- 로그(2.10.10.3, 8.23). 제안서는 로그에서 서명을 제거하라고 권고하는데, 포렌식은 서명된 원본이 증거가 될 수 있어 상충한다(이 책의 지적). 두 사본을 분리 보관하는 정책이 필요하다.
- 링크 상실(3.11.6). HEARTBEAT 위조와 하트비트 1 Hz 관례가 링크 상실 판정의 입력이다.
- 한국의 보안 규제(18.28). 항공보안·드론 보안 규제가 MAVLink 서명을 요구하는지는 이 장이 확인하지 못했다
(확인 필요).
9.5.15 함정과 한계
| 오해 | 실제 | 더 볼 곳 |
|---|---|---|
| MAVLink 2는 암호화된다 | 서명은 인증·무결성만이다. 평문이다 | 9.5.6, 9.5.10 |
| MAVLink 2이면 서명된다 | 서명은 선택이고 대부분의 망이 서명 없는 v2다 | 9.5.6.3 |
| 서명은 누가 보냈는지 증명한다 | 키 보유 여부만 인증한다. 보유자는 어떤 ID로도 서명한다 | 9.5.10 |
| CRC가 변조를 막는다 | CRC·CRC_EXTRA는 공개 정의로 누구나 계산한다 | 9.5.3 |
| 48비트라서 약하다 또는 충분하다 | 시도율과 키 수명이 정한다. 50 kbps에서 1일 $6\times10^{-8}$, 1년 $2.2\times10^{-5}$ | 9.5.8.1 |
| 하트비트 1 Hz가 규격이다 | 주기와 단절 판정은 링크마다 정한다. 1 Hz와 4~5회는 RF 링크의 전형값이다 | 9.5.5, 3.11.6 |
| 구성요소 ID로 장치 종류를 안다 | HEARTBEAT.type으로 판별한다. ID는 수동 할당이다 | 9.5.4 |
| 시스템 ID가 1바이트이니 기체 255대를 운용한다 | 지상통제소·SDK도 1~255를 사용하고 자동 할당이 없다 | 9.5.4 |
| 임무 업로드는 항상 성공한다 | 손실 20 %·100항목이면 19.6 %가 중단된다 | 9.5.9 |
| 이중 링크로 보내면 안전하다 | 순번이 링크마다 독립이어서 중복 제거 장치가 없다 | 9.5.5 |
| 메시지 정의는 영구적이다 | 폐기·대체·개발 중 표지가 있다(TRAJECTORY_REPRESENTATION_*는 2025-03 폐기) | 9.5.4 |
| 이 장의 위조 확률이 곧 암호 분석이다 | 이 장의 위조 확률은 모형 계산이다. 암호 분석이 아니다 | 9.5.10 |
미해결 문제. 서명 키의 표준적 회전·폐기 방식, 48비트 태그의 독립적 분석, 다중 링크에서의 재생 창과 중복 제거, 서명과 라우터 전달 규칙의 상호작용, 구현 간 서명 상호운용(QGroundControl·MAVSDK·pymavlink), 인증 환경에서 MAVLink의 입증 근거는 이 장의 자료로 답할 수 없다 (확인 필요).
9.5.16 체크포인트·연구 질문
체크포인트:
- v2 서명 패킷의 최소·최대 길이와 HEARTBEAT 서명 패킷의 길이를 구하라.
- 57,600 baud(8N1)에서 ATTITUDE 단독 최대율을 v1·v2·서명 v2로 구하라.
- 48비트 태그가 $P\le10^{-9}$을 만족하는 누적 시도 수를 구하고, 50 kbps·256비트 프레임에서 몇 분인지 구하라.
- 영숫자 8자 문자열 키의 전수 탐색 시간을 초당 $10^{10}$회 가정으로 구하라.
- 손실 10 %에서 100항목 임무 업로드의 중단 확률을 구하라.
- 한 흐름이 (시스템, 구성요소, 링크)이고 C 라이브러리 기본이 16이면, 기체 8대에 구성요소 3개씩이 단일 링크로 연결된 지상통제소에서 서명 수신이 어떻게 되는지 설명하라.
연구 질문(25.7에 모은다):
- 서명 키를 회전·폐기하는 프로토콜을 MAVLink 위에 어떻게 설계하고, 48비트 태그의 누적 시도 한계로 교체 주기를 어떻게 정하는가.
- 인증된 C2 링크 요구(8.11)를 MAVLink 서명과 링크 계층 보안의 조합으로 입증하는 근거는 무엇인가.
- 다중 링크에서 타임스탬프 재생 창과 중복 제거를 함께 설계하는 방법은 무엇인가.
- 비서명 허용 목록이 안전 판단(링크 상실·교통 정보)에 미치는 영향을 어떻게 시험하는가.
1차 출처(이 장):
- MAVLink 개발자 가이드(mavlink.io) 원본 마크다운, mavlink/mavlink-devguide 커밋 226d443(2026-10-29):
en/guide/serialization.md,mavlink_2.md,message_signing.md,routing.md,mavlink_version.md,xml_schema.md,define_xml_element.md,crc.md,message_rates.md,redundancy_deduplication.md,packet_loss.md,uavcan_interaction.md,en/services/{heartbeat,command,parameter,mission,high_latency,mavlink_id_assignment,ping,timesync,arm_authorization,ftp,tunnel,opendroneid,offboard_control,manual_control,index}.md. - mavlink/mavlink
message_definitions/v1.0/{minimal,standard,common,all}.xml커밋 6bf60db(2026-10-28). mavlink/c_library_v2checksum.h·mavlink_helpers.h·mavlink_types.h커밋 a2d0ecf(2026-10-28). ArduPilot/pymavlinkgenerator/mavparse.py·mavcrc.py커밋 03af8c2. - MAVLink 2.0 packet signing proposal(구글 문서 내보내기). PX4-Autopilot
docs/en/mavlink/message_signing.md커밋 36919f8(2026-10-31). ArduPilot Copter 문서 MAVLink2 Signing, ArduPilot 개발 문서 Security. - IETF RFC 2104(Bellare·Canetti·Krawczyk, 1997) 5절, RFC 8439(2018) 4절, RFC 9147(DTLS 1.3, 2022) 4절·4.5.3절.
- Allouch 외, MAVSec: Securing the MAVLink Protocol for Ardupilot/PX4 Unmanned Aerial Systems, arXiv:1905.00265(IWCMC 2019). Kwon 외, Empirical Analysis of MAVLink Protocol Vulnerability for Attacking Unmanned Aerial Vehicles, IEEE Access 6, 43203–43212(2018).
- 읽지 못함: Marty, Vulnerability Analysis of the MAVLink Protocol for Command and Control of Unmanned Aircraft(AFIT, 2014, 접근 차단). MAVLink 2 설계 문서. ASTM F3411, ASD-STAN prEN 4709-002. DO-326A·DO-356A.
다음 장: 9.6 — 오토파일럿 생태계와 미들웨어: PX4·ArduPilot·ROS 2/DDS·FPV 링크·독점 프로토콜. 이 장이 오토파일럿과 지상통제소 사이의 메시지 규격을 다루었다면, 9.6은 그 규격을 구현하는 생태계와 로봇 미들웨어, 독점 링크를 본다.