WMDRM(Windows Media Digital Rights Management)
DRM이 세계적인 Issue로 떠오르면서 Microsoft에서도 독자적인 DRM을 발표하였다.
이름하여, WMDRM.
초기버전 WMDRM은 ASF format 기반의 WMA, WMV파일을 시작하였으며, 차기 버전에서는
Image, Office 파일에 걸쳐 전반적인 데이터에도 적용할 것을 암시했다.
대체 이 WMDRM 이란 무엇이며, 어떻게 생겨먹은지를 알아보도록 하자.
(이 내용에서는 ASF포맷 기반의 WMA, WMV만 보도록 한다.)
참고로, WMDRM에서 손뗀지 좀 오래되다 보니, 가물가물한 부분은 살짝 생략하거나, 대충(ㅡ.ㅡ?) 설명하겠다.
1. ASF Format
WMDRM을 알기 위해서는 그 전에 ASF Format을 알아야 한다.
(ASF Specification Download URL:
http://www.microsoft.com/windows/windowsmedia/forpros/format/asfspec.aspx)
ASF 포맷의 구조는 이러하다. (<..>은 Optional)
----------------------------------
Header
- File Properties Object
- Stream Properties Object 1
...
...
- Stream Properties Object N
<Other Header Objects>
----------------------------------
Data Object
- Data Packet 1
- ...
- ...
- Data Packet M
----------------------------------
<Other top-level objects>
- Index Object 1
- ...
- Index Object K
- Simple Index Object 1
- ...
- Simple Index Object L
----------------------------------
2. Header
Header에는 이 파일의 출처가 어디며 어떻게 재생해야 하고, 시간은 어떻게 되는 등등 파일의 모든 정보가
들어 있다. Header의 Object는 Object별로 순서가 있는게 아니기 때문에 GUID라는 값을 사용해서 각 종류별로 Pasing을
하도록 해야 한다.
ASF파일의 Objects는 기본적으로 다음과 같이 구성된다.
----------------------------------
Object ID(GUID) - 128 bit
----------------------------------
Object Size - 64 bit
----------------------------------
Object Data - Object Size bit
----------------------------------
이제 Header를 Pasing해 보자.
ASF파일은 모두 Header Object로 시작한다.
Header부분에서도 가장 앞에 있어야 하며, 이 Header에 몇개의 Header Object가 있으며, Header의
전체 길이(Data Object의 바로 앞까지)를 나타낸다.
Name | GUID |
ASF_Header_Object | 75B22630-668E-11CF-A6D9-00AA0062CE6C |
ASF_Data_Object | 75B22636-668E-11CF-A6D9-00AA0062CE6C |
ASF_Simple_Index_Object | 33000890-E5B1-11CF-89F4-00A0C90349CB |
ASF_Index_Object | D6E229D3-35DA-11D1-9034-00A0C90349BE |
ASF_Media_Object_Index_Object | FEB103F8-12AD-4C64-840F-2A1D2F7AD48C |
ASF_Timecode_Index_Object | 3CB73FD0-0C4A-4803-953D-EDF7B6228F0C |
<표 1. Top Level ASF Object GUID>
파일을 Open해서 GUID(128bit)를 가져오면 첫번째로 ASF_Header_Object가 나온다.
Field name | Field type | Size (bits) |
Object ID | GUID | 128 |
Object Size | QWORD | 64 |
Number of Header Objects | DWORD | 32 |
Reserved1 | BYTE | 8 |
Reserved2 | BYTE | 8 |
<표 2. ASF Header Object>
그 다음 64bit는 Object Size이다. 현재 Object의 길이를 말해준다. 여기서 Object의 길이는 GUID로부터 끝나는 부분까지의
길이이다. 그 다음에 나오는 Number of Header Objects는 아래의 <표3>에 열거된 Header Object들의 갯수를 나타낸다.
이 Number of Header Objects의 수 만큼 loop를 돌려서 각 Object 값들을 pasing하면 되겠다.
Name | GUID |
ASF_File_Properties_Object | 8CABDCA1-A947-11CF-8EE4-00C00C205365 |
ASF_Stream_Properties_Object | B7DC0791-A9B7-11CF-8EE6-00C00C205365 |
ASF_Header_Extension_Object | 5FBF03B5-A92E-11CF-8EE3-00C00C205365 |
ASF_Codec_List_Object | 86D15240-311D-11D0-A3A4-00A0C90348F6 |
ASF_Script_Command_Object | 1EFB1A30-0B62-11D0-A39B-00A0C90348F6 |
ASF_Marker_Object | F487CD01-A951-11CF-8EE6-00C00C205365 |
ASF_Bitrate_Mutual_Exclusion_Object | D6E229DC-35DA-11D1-9034-00A0C90349BE |
ASF_Error_Correction_Object | 75B22635-668E-11CF-A6D9-00AA0062CE6C |
ASF_Content_Description_Object | 75B22633-668E-11CF-A6D9-00AA0062CE6C |
ASF_Extended_Content_Description_Object | D2D0A440-E307-11D2-97F0-00A0C95EA850 |
ASF_Content_Branding_Object | 2211B3FA-BD23-11D2-B4B7-00A0C955FC6E |
ASF_Stream_Bitrate_Properties_Object | 7BF875CE-468D-11D1-8D82-006097C9A2B2 |
ASF_Content_Encryption_Object | 2211B3FB-BD23-11D2-B4B7-00A0C955FC6E |
ASF_Extended_Content_Encryption_Object | 298AE614-2622-4C17-B935-DAE07EE9289C |
ASF_Digital_Signature_Object | 2211B3FC-BD23-11D2-B4B7-00A0C955FC6E |
ASF_Padding_Object | 1806D474-CADF-4509-A4BA-9AABCB96AAE8 |
<표 3. Header Object GUIDs>
각 Object들의 Field 값들은 모두 다르니 제일 처음에 언급한 ASF Specification의 [3. ASP top-level Header Object]
항목을 참고해서 pasing하시면 되겠다. Header pasing은 끝. ㅡ,.ㅡ;
3. Data Object
Data Object의 시작점은 Header Pasing에서 제일 처음에 나오는, ASF Header 데이터에서 가져온 Header Size값 만큼,
파일을 seek 하면 된다. ASF Header 특성상 Header Object들이 단위 별로 끊어져 있으므로, Header Pasing이 끝나는 부분에서
Data Object라고 생각하여 사용하지말고, 꼭 Header Size를 이용한 부분에서 Data Object라고 보는게 낫다.
Data Object 역시 GUID가 있다. <표 1>에서 두번째에 자리잡은 ASF_Data_Object 값이 그것이다.
Field name | Field type | Size (bits) |
Object ID | GUID | 128 |
Object Size | QWORD | 64 |
File ID | GUID | 128 |
Total Data Packets | QWORD | 64 |
Reserved | WORD | 16 |
Data Packets | See section 5.2 | varies |
<표 4. Data Object>
Object Size는 Data Object의 전체 사이즈를 나타낸다. File ID값은 unique한 값이라는데 그닥 재생하는데 상관은 없는듯 하다.
Total Data Packets이 있는데, 이는 Header Object중 ASF_File_Properties Object의 Packet Count와 일치해야 한다.
이 Packet에 대해서는 아래에서 자세히 알아보도록 한다.
그리고 Reserved는 임시로 마련해둔 값이므로 무시하고, Data Packets이라는 부분이 바로 재생하는 데이터, 즉 Packets의
실제 데이터가 들어가는 부분이다.
하나의 Packet의 Size는 64KB를 넘으면 안된다. 그래서 이를 넘는 크기의 Media인 경우 Packet단위로 짤려서 존재하며,
Packet의 총 갯수가 필요한 것이다.
4. Packet
Packet은 아래와 같이 구성된다.
---------------------------------------------------- ----------------------------------------------------
Error Correction Data(Optional) Error Correction Data(Optional)
---------------------------------------------------- ----------------------------------------------------
Payload Parsing Information
---------------------------------------------------- Or Opaque Data
Payload Data
---------------------------------------------------- ----------------------------------------------------
Padding Data(Optional) Padding Data(Optional)
---------------------------------------------------- ----------------------------------------------------
두가지 Structure가 있는데, 우측의 Opaque Data... ㅡ,.ㅡ 뭔지...;; 어떻게 Pasing하란 말인가;;; 일단 우측은 Pass.
Error Correction Data와 Padding Data는 Spec을 참고 한다. Optional이므로 그닥 중요한 내용은 아니다.
이제 Packet도 Pasing을 해보자.
Error Correction Data가 Optional이긴 하지만, 있는지 없는지를 확인 해야 한다.
Field name | Field type | Size (bits) | |
Error Correction Flags | BYTE | 8 | |
Error Correction Data Length | 4 (LSB) | ||
Opaque Data Present | 1 | ||
Error Correction Length Type | 2 | ||
Error Correction Present | 1 | ||
Error Correction Data | BYTE | varies |
<표 5. Error Correction Data>
만약 Error Correction Flags가 0이면 이 항목은 Pass, 0이 아니면, 스펙에 따라 Pasing하자.
그 다음이 Payload Pasing Information 이다.
Field name | Field type | Size (bits) | |
Length Type Flags | BYTE | 8 | |
Multiple Payloads Present | 1 (LSB) | ||
Sequence Type | 2 | ||
Padding Length Type | 2 | ||
Packet Length Type | 2 | ||
Error Correction Present | 1 | ||
Property Flags | BYTE | 8 | |
Replicated Data Length Type | 2 (LSB) | ||
Offset Into Media Object Length Type | 2 | ||
Media Object Number Length Type | 2 | ||
Stream Number Length Type | 2 | ||
Packet Length | BYTE, WORD or DWORD | 0, 8, 16, 32 | |
Sequence | BYTE, WORD or DWORD | 0, 8, 16, 32 | |
Padding Length | BYTE, WORD or DWORD | 0, 8, 16, 32 | |
Send Time | DWORD | 32 | |
Duration | WORD | 16 |
<표 6. Payload Information>
너무 긴데. 하나하나 설명을 해야 하나.... 휴..
자세한 내용은 꼭!!! Spec을 같이 봐달라... 표가 너무 많다.
먼저 Length Type Flags인 1Byte(8bit)를 읽어서 Multiple Payloads Present 값 부터,
Error Correction Present까지 5개의 항목에 해당하는 값을 구한다.
Multiple Payloads Present 는 Multiple Payload인지 아닌지,
(참고로 Packet은 이 Payload를 위한 집(house)라고 생각하면 되겠다.
WMA파일인 경우 1개의 Packet에 1개의 Payload가 일반적인데, WMV 와 같은 경우에는 Multiple Payload라고
해서 하나의 Packet내에 Payload가 두 개 존재한다. 아마도 음성과 영상이 포함되었을 것이다.)
Sequence Type은 Sequence Field의 단위(Sequence Field가 없다, BYTE, WORD, DWORD 중 하나)
Padding Length Type의 단위(Padding Length Field가 없다, BYTE, WORD, DWORD 중 하나)
Packet Length Type 단위(Packet Length Field가 없다, BYTE, WORD, DWORD 중 하나)
Error Correction Present(Error Correction의 유무)
등을 알 수 있다.
이와 같은 방법으로 Pasing한다. 스펙에 쉽게 잘 나와 있다.
5. Payload
이노무 시키... Payload만 하면 ASF Format은 끝이다.
자... Payload는 어떻게 생겼냐... 하면 이렇게 생겼다. 못생긴기..ㅡ.,ㅡㅋ 쩝.
각 Payload는 표와 같이 구성된다.
Field name | Field type | Size (bits) |
Stream Number | BYTE | 8 |
Media Object Number | BYTE, WORD, or DWORD | 0, 8, 16, 32 |
Offset Into Media Object | BYTE, WORD, or DWORD | 0, 8, 16, 32 |
Replicated Data Length | BYTE, WORD, or DWORD | 0, 8, 16, 32 |
Replicated Data | BYTE | varies |
Payload Data | BYTE | varies |
<표 7. Payload>
Payload에는 Single Payload와 Multiple Payload, 그리고 각각 Compressed Payload라는게 있다.
Payload 부분은 다음에 다시 자세히 분석해서 올려보도록 하겠다.
6. ASF에서 WMDRM 이 되는 과정.
오늘 WMDRM 스펙을 구했다. 이 부분을 다시 정리해서 올리도록하겠다. (2008-12-18)
원래글.
(이러한 ASF 구조에서 WMDRM은 Header부분의 Stream Properties Object에 WMDRM과 관련된
Object가 두개 정도 추가가 된다. Object Name과 GUID는 WMDRM PD(porting Device)의 문서에 나와 있다.
그리고 Packet의 Payload의 내용이 암호화 되어 있다.
ASF 파일의 Payload의 Decrypt 방법은 마지막 8Byte를 이용해서 Payload 별로 Decrypt하는데,
WMDRM에서는 Payload를 Decrypt하기 위해 또 다른 Key가 필요하다.
HDS 파일이라는 WMDRM에서 사용하는 License Management 파일이 있다. WMA 파일의 Header에서 KID를 가져온다. 이 값을 이용해 HDS 파일에서 Key를 꺼내고, Device의 Private Key를 이용해 복호화 해야 한다.)
흠..ㅡ,.ㅡ; 너무 간단하게 적었다.
WMDRM 문서를 찾게되면, 다시 정교하게 update를 하겠다. }
결국 가장 중요한 Payload와 WMDRM 에 관련된 사항이 빠졌다;;
문서를 꼭 찾아서 다시 올려보도록 하겠다. ㅡ,.ㅡ 시간이 더 필요하군아.
오랫만에 되새기니까, 가물가물하다. 암튼 WMDRM 기억에 남을 만하다.