라이선스 사이퍼 SDK 가이드

개요

본 문서는 안드로이드와 웹 애플리케이션을 대상으로 Widevine L3의 보안성을 강화하는 DRM 라이선스 사이퍼 SDK에 대해 안내합니다.

소프트웨어 수준의 보안을 제공하는 Widevine L3 DRM의 경우, TEE(Trusted Execution Environment) 기반의 하드웨어 보안을 지원하는 Widevine L1에 비해 해킹에 취약하다는 단점이 있습니다. 안드로이드 애플리케이션과 크롬 등의 브라우저에서 Widevine DRM 콘텐츠 재생 시, 라이선스 사이퍼 SDK을 적용하면 DRM 라이선스 요청을 암호화해 각종 해킹 툴에 의한 콘텐츠 키 유출을 방지할 수 있습니다.

라이선스 사이퍼와 함께 앱실링 서비스의 앱 보안 기능을 적용하면 안드로이드 앱에 대한 해킹 시도를 효과적으로 차단하여 콘텐츠 보안을 강화할 수 있습니다.

사전 요구 사항

라이선스 사이퍼 SDK를 이용하기 위해서는 다음과 같은 사항이 요구됩니다.

  • 엔터프라이즈 요금제 및 앱실링 서비스 가입
    • 라이선스 사이퍼를 이용하려면 PallyCon 엔터프라이즈 요금제에 가입해야 합니다. 또한 애플리케이션 보안 적용을 위해 앱실링 서비스 가입이 필요합니다.
    • PallyCon DRM 클라이언트 SDK (Widevine Android SDK, FPS iOS SDK 등) 대신 타사 플레이어와 연동하는 경우에도 동일한 조건이 적용됩니다.
  • 라이선스 사이퍼 SDK 요청
    • 라이선스 사이퍼 SDK는 헬프데스크를 통해 전달됩니다. 해당 SDK를 요청하려면 헬프데스크에 티켓을 생성해 주시기 바랍니다.
  • PallyCon Widevine Android SDK 또는 연동 가능한 타사 플레이어 사용
    • 라이선스 사이퍼 안드로이드 SDK는 PallyCon Widevine Android SDK 외에도 Google ExoPlayer 또는 Bitmovin 플레이어와 연동 가능합니다.
    • 다른 플레이어 솔루션과 라이선스 사이퍼 SDK 연동이 필요한 경우에는 헬프데스크로 문의해 주시기 바랍니다.
  • 키 테이블 파일 다운로드
    • 라이선스 요청 데이터의 암호화에 사용되는 WBC(WhiteBox Crypto) 키 테이블을 PallyCon 콘솔에서 다운로드 받아야 합니다. (멀티 DRM > DRM 세팅 > 라이선스 사이퍼)
    • 다운로드 받은 키 테이블 파일은 라이선스 사이퍼를 적용할 안드로이드 앱에 포함시켜 배포합니다.

안드로이드 라이선스 사이퍼 SDK

안드로이드용 라이선스 사이퍼 SDK는 적용 대상에 따라 다음과 같은 방법으로 연동됩니다. 두 가지 연동 방식에 대한 자세한 사항은 SDK에 포함된 샘플 프로젝트를 참고하시기 바랍니다.

PallyCon Widevine Android SDK 연동

  1. PallyCon 콘솔에서 다운로드한 키 테이블 파일을 안드로이드 애플리케이션 프로젝트의 assets 폴더에 복사합니다.
  2. 헬프데스크를 통해 전달받은 라이선스 사이퍼 SDK의 압축을 해제합니다.
  3. PallyConLicenseCipher.aar 파일을 프로젝트의 /module/libs/ 폴더에 복사합니다.
  4. build.gradle (app)에 다음과 같은 설정을 추가합니다.
dependencies {
  ...
  // If the pallycon widevine sdk is included in the existing 'project/module/libs/', omit it.
  implementation 'com.pallycon:widevine:x.x.x' 

  implementation fileTree(dir: 'libs', include: ['*.aar'])
  ...
}
  1. Widevine Android SDK의 DRM 설정 부분에 다음과 같이 키 테이블 경로를 추가합니다.
// Enter DRM-related information.
val config = PallyConDrmConfiguration(
 siteId = "site id",
 customData = "content auth data",
 httpHeaders = mutableMapOf(), // custom header
 drmLicenseUrl = "request license server url",
 licenseCipherPath = "key table file path in assets" // ex) plc-kt-test.bin
)

val data = ContentData(
 contentId = "content id",
 url = "content URL",
 localPath = "Download location where content will be stored",
 drmConfig = config,
 cookie = null
)

val wvSDK = PallyConWvSDK.createPallyConWvSDK(
 Context, // Context
 data
)

타사 플레이어 솔루션 연동

  1. PallyCon 콘솔에서 다운로드한 키 테이블 파일을 안드로이드 애플리케이션 프로젝트의 assets 폴더에 복사합니다.
  2. 헬프데스크를 통해 전달받은 라이선스 사이퍼 SDK의 압축을 해제합니다.
  3. PallyConLicenseCipher.aar 파일을 프로젝트의 /module/libs/ 폴더에 복사합니다.
  4. build.gradle (app)에 다음과 같은 설정을 추가합니다.
dependencies {
  ...
  // If the pallycon widevine sdk is included in the existing 'project/module/libs/', omit it.
  implementation 'com.pallycon:widevine:x.x.x' 

  implementation fileTree(dir: 'libs', include: ['*.aar'])
  ...
}
  1. 라이선스 사이퍼 라이브러리를 임포트합니다.
import com.pallycon.licensecipher.LicenseCipher
  1. Widevine 라이선스 요청 시, 라이선스 사이퍼를 이용해 요청 데이터를 암호화합니다.
// If you use ExoPlayer, you will need to inherit the 'MediaDrmCallback' and implement your own license request process. 
// licenseData is the widevine request license data and the data type is ByteArray.
val outputData = ByteArray(licenseData.size)
// create license cipher, path = The path to the Asset directory. ex) plc-kt-test.bin
// You can download the table file from the PallyCon console.
val licenseCipher = LicenseCipher.createLicenseCipher(context, tablePath)
// doCipher
if (licenseCipher.doCipher(licenseData, outputData)) {
  // requestData is the data to include in the body when communicating with the server API.
  requestData = outputData
}
서드파티 플레이어 솔루션에 라이선스 사이퍼 SDK를 연동하기 위해서는 해당 플레이어에서 DRM 라이선스 요청에 대한 콜백 API를 제공해야 합니다. 구글 ExoPlayer의 경우 MediaDrmCallback 인터페이스를 통해 해당 기능이 지원되며, 상용 플레이어 솔루션 중에도 유사한 API가 제공되는 경우가 있습니다. (예: Bitmovin Player)

크롬 라이선스 사이퍼 SDK

크롬용 라이선스 사이퍼 SDK를 이용하면 웹 애플리케이션에서의 Widevine 키 유출을 방지할 수 있습니다. 해당 SDK는 자바스크립트와 웹어셈블리로 구현되어 있으며, DRM 라이선스 요청에 대한 콜백 인터페이스가 지원되는 임의의 HTML5 플레이어와 연동이 가능합니다.

크롬 라이선스 사이퍼 SDK는 다음과 같은 모듈로 구성되어 있습니다.

  • DRMLicenseCipher.js: Widevine 라이선스 요청 데이터(챌린지)의 암호화 기능이 구현된 자바 스크립트 파일. 보안을 위해 난독화 처리됨.
  • wbwflea.wasm: 암호화 키 보안을 위해 사용되는 WBC(White Box Crypto) 모듈. 웹 어셈블리로 구현.

크롬 라이선스 사이퍼 적용

크롬 라이선스 사이퍼 SDK는 다음과 같은 과정으로 고객사의 웹 애플리케이션에 적용할 수 있습니다.

  1. 서버에 SDK 모듈 업로드
  • 고객사 서비스에서 운영하는 웹 서버에 SDK 모듈(.js, .wasm 파일)을 업로드합니다. 두 파일은 동일한 경로 상에 위치해야 합니다.
  • 웹 애플리케이션에서 DRMLicenseCipher.js 파일을 링크할 수 있어야 합니다.
  1. JS 스크립트 추가
  • 웹 애플리케이션의 HTML 코드에 다음과 같이 해당 JS 파일에 대한 링크를 추가합니다.
    <script src="DRMLicenseCipher.js"></script>
    
  1. License Cipher 모듈 초기화
  • 웹 페이지 로드 시 다음과 같은 코드를 통해 License Cipher 모듈을 생성하고 초기화 합니다.
  • 필요에 따라 해당 모듈에서 발생하는 에러 및 동작 상황에 대한 이벤트를 처리합니다.
  • prepareEncryption 함수의 입력 값은 고객사의 PallyCon 서비스 계정에서 사용하는 사이트 ID(네자리 영숫자)를 사용합니다.
    // Create a DRMLicenseCipher instance
    const drmCipher = new DRMLicenseCipher();
    
    // Register an event
    drmCipher.on('PallyConError', (event) => {
        console.error('Error event received:', event);
    });
    
    drmCipher.on('PallyConState', (event) => {
        console.log('State event received:', event);
    });
    
    drmCipher.on('DownloadProgress', (event) => {
        console.log('Download progress:', event);
    });
    
    // Preparing for encryption
    async function prepareEncryption(siteId) {
        const isPrepared = await drmCipher.prepare(siteId);
        if (isPrepared) {
            console.log('Encryption preparation successful.');
        } else {
            console.error('Encryption preparation failed.');
        }
    }
    
최초 실행 시 prepareEncryption 함수 내에서는 입력된 사이트 ID 값에 대한 WBC 키 테이블 파일이 PallyCon 서버로부터 자동으로 다운로드됩니다. 이후에는 해당 브라우저의 로컬 저장소에 캐시된 키 테이블이 사용됩니다.
  1. DRM 라이선스 요청 암호화
  • HTML5 플레이어에서 제공하는 DRM 라이선스 요청 콜백 API를 통해 해당 요청 데이터(Body)를 License Cipher 모듈로 암호화합니다.
  • 다음은 Shaka Player에서 지원하는 API로 구현된 예제입니다. 콜백 API 구현은 플레이어 솔루션에 따라 다를 수 있습니다.
    player.getNetworkingEngine().registerRequestFilter(async function (type, request) {
        if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
            request.headers['pallycon-customdata-v2'] = customdata;
            if (request.body.byteLength > 3) {
                const encodedData = arrayBufferToBase64(request.body);
                const responseData = await cipher.encryptData(encodedData);
                const decodedData = base64ToArrayBuffer(responseData);
                request.body = decodedData;
            }
        }
    });
    
  1. 데이터 리셋 및 모듈 릴리즈
  • 라이선스 요청 데이터 암호화 후에는 다음과 같은 방법으로 License Cipher 모듈을 리셋하고 릴리즈합니다.
    // Data reset
    async function resetData() {
        const isReset = await drmCipher.reset();
        if (isReset) {
            console.log('Data reset successful.');
        } else {
            console.error('Data reset failed.');
        }
    }
    
    // Data release
    async function releaseData() {
        const isReleased = await drmCipher.release();
        if (isReleased) {
            console.log('Data release successful.');
        } else {
            console.error('Data release failed.');
        }
    }
    

실제 플레이어와의 연동 구현은 SDK에 포함된 샘플 페이지(Shaka Player 기반)를 참고하시기 바랍니다.

라이선스 토큰에 라이선스 사이퍼 활성화

클라이언트 앱에 라이선스 사이퍼 SDK를 적용한 후에는 해당 앱에서 사용되는 라이선스 토큰에 아래 예시와 같이 암호화 플래그를 활성화합니다.

"security_policy": [
  {
    ...
    "widevine": {
      ...
      "enable_license_cipher": true
    },
    ...
  }
]

해당 플래그는 라이선스 사이퍼 SDK가 적용된 버전의 클라이언트 앱을 대상으로만 true로 설정해야 하며, 그 외에 라이선스 요청 데이터가 암호화되지 않은 이전 버전 안드로이드 앱 및 기타 클라이언트(스마트TV 등)에 대해서는 기존과 같이 해당 플래그가 생략되거나 false로 설정된 토큰이 적용되어야 합니다.

enable_license_cipher 설정 값과 실제 라이선스 요청 데이터의 암호화 여부가 일치하지 않는 경우, 서버에서의 처리 실패로 라이선스 발급 에러가 발생하게 됩니다.

암호화 미적용 요청 차단

클라이언트 앱에 라이선스 사이퍼 기능을 적용한 후에는 해당 앱에서의 라이선스 요청만 허용되도록 암호화 미적용 요청을 차단해야 합니다. DRM 기능의 신규 도입 여부에 따라 다음과 같은 방법으로 차단을 설정합니다.

신규 서비스에 도입하는 경우

라이선스 사이퍼를 신규 서비스에 도입하는 경우, 라이선스 사이퍼가 적용된 클라이언트 앱이 스토어에 등록되면 다음과 같이 암호화가 적용되지 않은 라이선스 요청을 차단합니다.

  1. PallyCon 콘솔 로그인
  2. 멀티DRM > DRM 세팅 화면에서 라이선스 사이퍼 설정의 암호화 미적용된 라이선스 요청 허용 여부 옵션을 차단으로 변경

위 설정 이후에는 안드로이드 앱으로부터의 Widevine 라이선스 요청은 라이선스 사이퍼 SDK를 통해 암호화된 경우에만 정상적으로 처리되며, 암호화가 미적용된 요청은 해킹 시도로 간주되어 DRM 라이선스 발급이 거부됩니다.

기존 서비스에 적용하는 경우

이미 DRM 콘텐츠를 서비스하고 있는 경우, 라이선스 사이퍼 솔루션 도입 과정에서 사용자 불편을 최소화 하려면 대부분의 사용자들이 신규 버전 앱으로 업데이트할 때까지 기존 버전에서의 암호화되지 않은 요청도 허용해야 합니다.

  1. 클라이언트 앱에 라이선스 사이퍼 SDK를 적용
  2. 신규 버전의 앱에 대해서 토큰 규격의 enable_license_cipher 항목을 true로 적용 (기본값: false)
  3. 업데이트된 앱을 스토어에 등록 후 사용자들에게 업데이트 요청 공지
  4. 대부분의 사용자가 업데이트를 완료하면 PallyCon 콘솔에서 암호화 미적용된 라이선스 요청 허용 여부 옵션을 차단으로 변경

토큰 프록시 방식 연동

고객사 시스템에서 운영하는 프록시 서버를 통해 DRM 라이선스 연동을 하는 경우, 프록시에서 생성하는 라이선스 토큰에 클라이언트 환경에 따라 enable_license_cipher 항목을 true로 설정해야 합니다. (라이선스 사이퍼 SDK가 적용된 안드로이드 앱 대상)

그 외에 프록시 서버에서 처리되는 라이선스 서버와 클라이언트 간의 요청 데이터와 응답 데이터에 대한 전달은 라이선스 사이퍼 적용 여부와 무관하게 기존과 동일한 방식으로 이루어집니다.

이전
다음