비콘 앱을 사용한 포렌식 워터마킹

이 항목에서는 Beacon 앱으로 Forensic Watermarking을 구현하는 방법을 배웁니다.

서문

Brightcove는 NAGRA 와 협력하여 Beacon 앱과 함께 Forensic Watermarking을 제공하여 프리미엄 콘텐츠를 불법 복제 및 무단 콘텐츠 공유로부터 보호합니다. 이 기능을 통해 고객은 콘텐츠 유출의 출처를 식별하고 적절한 조치를 취할 수 있습니다.

다음 다이어그램은 개요를 보여줍니다.

  • 콘텐츠 준비
    • Forensic Watermark는 Nagra의 SDK를 사용하여 트랜스코딩하는 동안 비디오에 포함된 보이지 않는 워터마크입니다.
    • Ingestion은 2개의 VOD 변환을 생성합니다. 하나는 워터마크 A이고 다른 하나는 워터마크 B입니다. 두 변환 모두 Video Cloud에서 동일한 타이틀의 일부입니다.
  • 배달
    • 콘텐츠 재생 시 Forensic Watermark 토큰을 플레이어에게 제공한 후 CDN에서 콘텐츠를 요청하는 URL에 포함
    • CDN은 토큰을 해석하고 A/B 세그먼트의 올바른 순서로 비디오를 시청자에게 전달합니다.
개요 다이어그램
포렌식 워터마킹 개요

요구 사항

이 기능을 지원하려면 다음 요구 사항이 필요합니다.

  • 비콘 앱은 OIDC 인증을 사용해야 합니다.
  • VOD 자산에만 사용 가능
  • 워터마크가 있는 비디오에는 MP4 변환이 생성되지 않습니다.

설정

Brightcove의 Forensic Watermarking 솔루션을 지원하려면 다음 설정이 필요합니다.

  1. 고객 비디오 클라우드 계정:
    • Dynamic Delivery에 대해 고객의 계정이 활성화되어 있는지 확인하십시오.
    • Forensic Watermarking에 대한 고객 계정을 활성화하려면 고객 지원 티켓을 여십시오. Video Cloud의 유료 애드온입니다.
  2. 고객은 NAGRA 에서 라이선스 키를 받습니다.
  3. 고객은 포렌식 워터마킹 토큰(WMT)에서 사용하고 CDN에서 해독할 공개-개인 키 쌍을 생성합니다. 예제는 아래 섹션을 참조하십시오.
  4. 고객은 NAGRA에서 제공하는 스크립트를 사용하여 포렌식 워터마킹 토큰(WMT)을 생성합니다.
  5. 고객에게 워터마킹 토큰(WMT)을 앱으로 전달할 클레임의 이름을 요청합니다. 이 클레임을 Beacon 팀과 공유하여 Beacon Master CMS에서 구성할 수 있습니다.

공개-개인 키 쌍 생성

공개-개인 키 쌍을 생성하는 방법에는 여러 가지가 있습니다. 다음은 몇 가지 예입니다.

배쉬 스크립트 예제:

키 쌍을 생성하는 예제 스크립트:

#!/bin/bash
set -euo pipefail

NAME=${1:-}
test -z "${NAME:-}" && NAME="brightcove-forensic-watermarking-key-$(date +%s)"
mkdir "$NAME"

PRIVATE_PEM="./$NAME/private.pem"
PUBLIC_PEM="./$NAME/public.pem"
PUBLIC_TXT="./$NAME/public_key.txt"

ssh-keygen -t rsa -b 2048 -m PEM -f "$PRIVATE_PEM" -q -N ""
openssl rsa -in "$PRIVATE_PEM" -pubout -outform PEM -out "$PUBLIC_PEM" 2>/dev/null
openssl rsa -in "$PRIVATE_PEM" -pubout -outform DER | base64 > "$PUBLIC_TXT"

rm "$PRIVATE_PEM".pub

echo "Public key to saved in $PUBLIC_TXT"

스크립트를 실행합니다.

$ bash keygen.sh
사용 예제Go

Go프로그래밍 언어를 사용하여 키 쌍을 생성하는 예:

package main
  
  import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "flag"
    "fmt"
    "io/ioutil"
    "os"
    "path"
    "strconv"
    "time"
  )
  
  func main() {
    var out string
  
    flag.StringVar(&out, "output-dir", "", "Output directory to write files into")
    flag.Parse()
  
    if out == "" {
      out = "rsa-key_" + strconv.FormatInt(time.Now().Unix(), 10)
    }
  
    if err := os.MkdirAll(out, os.ModePerm); err != nil {
      panic(err.Error())
    }
  
    priv, err := rsa.GenerateKey(rand.Reader, 2048)
    if err != nil {
      panic(err.Error())
    }
  
    privBytes := x509.MarshalPKCS1PrivateKey(priv)
  
    pubBytes, err := x509.MarshalPKIXPublicKey(priv.Public())
    if err != nil {
      panic(err.Error())
    }
  
    privOut, err := os.OpenFile(path.Join(out, "private.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
      panic(err.Error())
    }
  
    if err := pem.Encode(privOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes}); err != nil {
      panic(err.Error())
    }
  
    pubOut, err := os.OpenFile(path.Join(out, "public.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
      panic(err.Error())
    }
  
    if err := pem.Encode(pubOut, &pem.Block{Type: "PUBLIC KEY", Bytes: pubBytes}); err != nil {
      panic(err.Error())
    }
  
    var pubEnc = base64.StdEncoding.EncodeToString(pubBytes)
  
    var pubEncOut = path.Join(out, "public_key.txt")
    if err := ioutil.WriteFile(pubEncOut, []byte(pubEnc+"\n"), 0600); err != nil {
      panic(err.Error())
    }
  
    fmt.Println("Public key saved in " + pubEncOut)
  }
  

node.js 사용 예제

node.js 를 사용하여 키 페어를 생성하는 예:

var crypto = require("crypto");
  var fs = require("fs");
  
  var now = Math.floor(new Date() / 1000);
  var dir = "rsa-key_" + now;
  fs.mkdirSync(dir);
  
  crypto.generateKeyPair(
    "rsa",
    {modulusLength: 2048},
    (err, publicKey, privateKey) => {
      fs.writeFile(
        dir + "/public.pem",
        publicKey.export({ type: "spki", format: "pem" }),
        err => {}
      );
      fs.writeFile(
        dir + "/public_key.txt",
        publicKey.export({ type: "spki", format: "der" }).toString("base64") +
          "\n",
        err => {}
      );
      fs.writeFile(
        dir + "/private.pem",
        privateKey.export({ type: "pkcs1", format: "pem" }),
        err => {}
      );
    }
  );
  
  console.log("Public key saved in " + dir + "/public_key.txt");

지원되는 기능 및 제한 사항

Forensic Watermarking을 사용할 때 지원되는 기능 및 제한 사항 목록은 개요를 참조하십시오. 포렌식 워터마킹문서.