HTTPS 사설 인증서 생성과 와우자 엔진 적용 방법

This article is available in English.

HTTPS HLS 스트림을 전송하려면 송출 프로그램이 서버의 자체 서명 인증서를 신뢰해야 한다. 파이썬 cryptography 패키지로 PushCap 서버용 인증서와 개인 키를 생성하고, 와우자가 사용하는 Java cacerts에 인증서를 등록한 뒤 적용 여부를 확인하는 과정을 설명한다.

HTTPS 인증서와 HLS

HLS는 웹 서비스에 널리 사용되는 HTTP를 이용해 동영상 데이터와 재생목록을 전송하는 스트리밍 방식이다.

인터넷 초기부터 사용된 HTTP에서는 여러 보안 문제가 대두되었고, 이에 대응하기 위해 HTTPS가 널리 사용되면서 현대 인터넷 전송의 표준 방식이 되었다. HTTPS는 전송되는 데이터를 키(key)를 사용해 암호화하고, 통신하는 대상의 진위 여부를 인증서(certificate)로 확인해 통신의 신뢰성을 높인다.

이러한 보안 대책들은 실제 서비스 환경에서 큰 도움이 되지만 개발 환경에서는 그다지 도움이 되지 못한다. 시험 환경의 인증서는 정식으로 등록되지 않은 상태이기 때문에 인증 절차에 문제가 생기고 상호 연동이 실패하기 때문이다.

따라서 공인 인증서를 사용할 수 없는 시험 환경에서는 자체 서명 인증서와 개인 키를 생성해 시험용 서버에 적용하고, 접속하는 프로그램이 해당 인증서를 신뢰하도록 별도로 등록해 주어야 한다.

본 글에서는 파이썬을 이용해 PushCap과 같은 사설 HLS PUSH 서버에서 사용할 자체 서명 인증서와 개인 키를 생성하고, 해당 인증서를 와우자 스트리밍 엔진(Wowza Streaming Engine, 이하 와우자)이 사용하는 Java 신뢰 저장소에 등록해 HTTPS HLS PUSH 스트림을 전송하는 방법을 설명한다.

파이썬을 이용한 인증서 생성 방법

파이썬 실행 환경 준비

  1. 파이썬 설치

    본 예제는 파이썬을 이용해 진행한다. 따라서 키와 인증서를 생성하려는 PC에 파이썬이 설치되어 있어야 한다.

  2. 추가 패키지 설치

    다음의 명령어를 통해 프로그램 실행에 필요한 cryptography 패키지를 설치해 준다.

    py -m pip install cryptography

프로그램 파일 생성

적당한 디렉토리를 생성하고, 아래의 코드 내용을 복사해 GenCert.py라는 파일로 저장해 준다.

from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import datetime

# 도메인 이름을 여기에 넣어준다. 이 주소가 스트리밍 프로그램에 입력될 주소이다.
domain_name = u"b.upload.youtube.com"

# 1. 개인 키 생성
key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)

# 2. 개인 키를 파일에 저장 (key.pem)
with open("key.pem", "wb") as f:
    f.write(key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption(),
    ))

# 3. 자체 서명을 위한 인증서 정보 설정 (Common Name을 수정)
subject = issuer = x509.Name([
    x509.NameAttribute(NameOID.COUNTRY_NAME, u"KR"),
    x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Jeju-do"),
    x509.NameAttribute(NameOID.LOCALITY_NAME, u"Mola-si"),
    x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"EQMaker"),
    x509.NameAttribute(NameOID.COMMON_NAME, domain_name),
])

# 4. 인증서 생성 및 서명
cert = x509.CertificateBuilder().subject_name(
    subject
).issuer_name(
    issuer
).public_key(
    key.public_key()
).serial_number(
    x509.random_serial_number()
).not_valid_before(
    datetime.datetime.now(datetime.timezone.utc)
).not_valid_after(
    datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365)
).add_extension(
    x509.SubjectAlternativeName([x509.DNSName(domain_name)]),
    critical=False,
).sign(key, hashes.SHA256())

# 5. 인증서를 파일에 저장 (cert.pem)
with open("cert.pem", "wb") as f:
    f.write(cert.public_bytes(serialization.Encoding.PEM))

print(f"'{domain_name}'  cert.pem / key.pem 생성됨.")

b.upload.youtube.com 부분에 사용하고자 하는 HTTPS URL의 호스트 이름을 입력해 준다. 즉, 이 인증서가 적용된 서버는 자기가 b.upload.youtube.com라고 주장하게 되는 것이다.

인증서 생성

콘솔 창에서 GenCert.py 파일이 있는 디렉토리로 이동해 코드를 실행시켜 준다. 아래와 같이 생성됨이라는 메시지가 출력되면 정상적으로 암호 키와 인증서가 생성되었다는 의미이다.

Microsoft Windows [Version 10.0.20348.4052]
(c) Microsoft Corporation. All rights reserved.
D:\>cd HLSWEB
D:\HLSWEB>py GenCert.py
'b.upload.youtube.com' cert.pem / key.pem 생성됨.

생성된 cert.pem 파일과 key.pem 파일을 PushCap.py 실행 디렉토리로 복사한다. 별도의 수신 서버를 사용하는 경우 해당 서버에 인증서와 키 파일을 등록해 준다.

OBS와 같이 별도의 인증서와 키 검증 기능이 없는 스트리밍 프로그램을 사용하고 있다면 추가 작업 없이도 HTTPS HLS 스트림을 전송할 수 있게 된다. 하지만 와우자와 같이 서버 인증서의 신뢰성을 검증하는 경우 공인 인증서가 아니기 때문에 아래에서 설명할 추가적인 등록 절차가 필요하다.

와우자 스트리밍 엔진에 사설 인증서 적용하기

와우자 같은 상업용 스트리밍 프로그램의 경우 인증서를 자체적으로 추가 검증하기도 한다. 자체 서명 인증서는 기본 신뢰 저장소에 등록되어 있지 않으므로, PushCap 서버가 제시하는 인증서를 와우자의 Java 신뢰 저장소에 직접 등록해야 한다.

와우자 스트리밍 엔진 사설 인증서 적용 절차

  1. 와우자 서비스 정지: 와우자 서비스를 정지시킨다.
  2. 콘솔 접속: 관리자 권한을 사용할 수 있는 콘솔(DOS 창 등)을 연다.
  3. 자바 도구 디렉토리 이동

    와우자를 설치하며 함께 설치되는 자바 도구 디렉토리로 이동한다. 기본 경로는 [와우자 기본 설치 경로]/jre/bin이다. 자바를 별도로 설치해 사용하거나 와우자 버전이 다른 경우에는 기본 경로가 달라질 수 있으므로 주의한다.

  4. 인증서 파일 등록

    bin 디렉토리에는 keytool이라는 실행 파일이 존재한다. 다음의 명령을 입력해 인증서 파일을 등록해 준다.

    keytool -importcert -alias "[인증서 이름]" -keystore "[인증서 저장소]" -storepass changeit -file "[인증서 파일]"
    [인증서 이름]
    와우자 스트리밍 엔진에서 사용할 인증서의 이름으로, 사용자가 임의로 지정할 수 있다.
    [인증서 저장소]
    인증서가 저장될 위치로, 와우자가 사용하는 JRE 디렉토리 내부의 인증서 저장소 위치로, 기본 경로는 [와우자 설치 경로]\jre\lib\security\cacerts이다.
    [인증서 파일]
    등록할 인증서 파일(.pem)의 경로와 파일 이름

    changeit은 Java cacerts 신뢰 저장소의 초기 비밀번호이다. 관리자가 비밀번호를 변경한 환경에서는 실제 비밀번호로 바꾸어 입력해야 한다.

와우자 스트리밍 엔진에 인증서를 적용하고 확인하는 예

다음은 윈도우 환경의 와우자 스트리밍 엔진에 사설 인증서를 적용하는 실제 절차의 예로, 환경은 다음과 같다.

운영체제
윈도우 서버 2022
와우자 버전
4.8.25+2
인증서 파일 경로
D:\HLSWEB\cert.pem
  1. 관리자 권한으로 콘솔 창(DOS 창)을 띄운다.
  2. 와우자 엔진 서비스 정지
    C:\>sc stop WowzaStreamingEngine4825+2
    
    SERVICE_NAME: WowzaStreamingEngine4825+2
            TYPE               : 10  WIN32_OWN_PROCESS
            STATE              : 3  STOP_PENDING
                                    (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
            WIN32_EXIT_CODE    : 0  (0x0)
            SERVICE_EXIT_CODE  : 0  (0x0)
            CHECKPOINT         : 0x0
            WAIT_HINT          : 0x7d0
  3. 인증서 등록
    C:\>Program Files\Wowza Media Systems\Wowza Streaming Engine 4.8.25+2\jre\bin>keytool.exe -importcert -alias "YouTubeLocal" -keystore "C:\Program Files\Wowza Media Systems\Wowza Streaming Engine 4.8.25+2\jre\lib\security\cacerts" -storepass changeit -file "D:\HLSWEB\cert.pem"
    Warning: use -cacerts option to access cacerts keystore
    Owner: CN=b.upload.youtube.com, O=EQMaker, L=Mola-si, ST=Jeju-do, C=KR
    Issuer: CN=b.upload.youtube.com, O=EQMaker, L=Mola-si, ST=Jeju-do, C=KR
    Serial number: 389c81b7d9e5452c8cbace6436a99aff004376
    Valid from: Mon Aug 25 23:34:59 KST 2025 until: Tue Aug 25 23:34:59 KST 2026
    Certificate fingerprints:
             SHA1: AA:BB:CC:DD:EE:00:AA:BB:CC:DD:EE:00:65:33:A0:A8:44:55:C0:54
             SHA256: AA:BB:CC:DD:EE:00:AA:BB:CC:DD:EE:FF:00:AA:BB:CC:DD:EE:25:9E:AD:00:54:DE:D0:AE:52:97:1C:A1:85:59
    Signature algorithm name: SHA256withRSA
    Subject Public Key Algorithm: 2048-bit RSA key
    Version: 3
    
    Extensions:
    
    #1: ObjectId: 2.5.29.17 Criticality=false
    SubjectAlternativeName [
      DNSName: b.upload.youtube.com
    ]
    
    Trust this certificate? [no]:  yes
    Certificate was added to keystore
  4. 인증서 등록 확인
    C:\Program Files\Wowza Media Systems\Wowza Streaming Engine 4.8.25+2\jre\bin>keytool -list -cacerts
    Enter keystore password:Enter
    
    *****************  WARNING WARNING WARNING  *****************
    * The integrity of the information stored in your keystore  *
    * has NOT been verified!  In order to verify its integrity, *
    * you must provide your keystore password.                  *
    *****************  WARNING WARNING WARNING  *****************
    
    Keystore type: JKS
    Keystore provider: SUN
    
    Your keystore contains 93 entries
    
    ... (전략) ...
    youtubelocal, 2025 Aug 26, trustedCertEntry,
    Certificate fingerprint (SHA-256): AA:BB:CC:DD:EE:00:AA:BB:CC:DD:EE:FF:00:AA:BB:CC:DD:EE:25:9E:AD:00:54:DE:D0:AE:52:97:1C:A1:85:59
    ... (생략) ...

    위와 같이 등록한 이름의 인증서(이 예에서는 youtubelocal)가 존재하면 정상적으로 등록되었다는 의미이다.

  5. 와우자 엔진 서비스 재시작
    C:\>sc start WowzaStreamingEngine4825+2
    SERVICE_NAME: WowzaStreamingEngine4825+2
            TYPE               : 10  WIN32_OWN_PROCESS
            STATE              : 2  START_PENDING
                                    (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
            WIN32_EXIT_CODE    : 0  (0x0)
            SERVICE_EXIT_CODE  : 0  (0x0)
            CHECKPOINT         : 0x0
            WAIT_HINT          : 0x7d0
            PID                : 4356
            FLAGS              :

FAQ

HLS 전송에 인증서가 필요한 이유는 무엇인가?

HLS 자체가 반드시 인증서를 요구하는 것은 아니다. 그러나 YouTube HLS PUSH처럼 HTTPS를 사용하는 전송에서는 서버의 신원을 확인하고 데이터를 암호화하기 위해 인증서가 필요하다. HTTP로만 전송한다면 인증서는 필요하지 않지만 통신 내용이 암호화되지 않는다.

사설 인증서와 공인 인증서의 차이는 무엇인가?

공인 인증서는 운영체제와 프로그램이 기본적으로 신뢰하는 공인 인증 기관에서 발급한다. 사설 인증서는 자체 서명하거나 내부 인증 기관에서 발급하므로 접속하는 프로그램에 별도로 신뢰 등록해야 한다. 두 인증서의 가장 큰 차이는 암호화 기능보다 기본 신뢰 여부에 있다.

키와 인증서의 차이는 무엇인가?

개인 키는 서버가 소유권을 증명하고 TLS 통신을 설정하는 데 사용하는 비밀 정보이며 외부에 공개해서는 안 된다. 인증서는 서버 이름, 공개 키, 발급자와 유효기간 등의 정보를 담고 있으며 접속하는 프로그램에 공개된다. 인증서와 개인 키는 서로 대응하는 한 쌍이어야 한다.

인증서가 없어도 키만으로 HTTPS 전송이 가능한가?

일반적인 HTTPS 통신에서는 불가능하다. 서버는 인증서와 이에 대응하는 개인 키를 함께 사용해야 한다. 개인 키만으로는 클라이언트가 접속 대상의 신원을 확인할 수 없으므로 정상적인 HTTPS 서버로 동작할 수 없다.

도메인 주소 대신 IP 주소로 인증서를 발급할 수 있는가?

가능하다. IP 주소용 인증서는 SAN에 도메인 이름이 아닌 IP 주소를 기록해야 한다. 파이썬 cryptography에서는 x509.DNSName()이 아니라 x509.IPAddress()를 사용한다. 다만 사설 IP 주소는 공인 인증서 발급이 어렵고 주소가 변경될 수 있어 주로 고정된 시험 환경이나 내부 시스템에서 사용한다.

와우자 스트리밍 엔진은 모든 플랫폼의 인증서를 가지고 있는 것인가?

아니다. 와우자가 사용하는 Java 신뢰 저장소에는 모든 서버의 인증서가 아니라 신뢰할 수 있는 주요 인증 기관의 루트 인증서와 중간 인증서가 들어 있다. 와우자는 서버가 제시한 인증서가 이 신뢰 체계로 검증되는지 확인하며, 자체 서명 인증서는 별도로 등록해야 한다.

왜 와우자에는 개인 키가 아니라 인증서만 등록하는가?

개인 키는 HTTPS 수신 서버인 PushCap이 보관해야 한다. 와우자는 해당 서버에 접속하는 클라이언트이므로 서버가 제시하는 인증서를 신뢰 저장소에 등록하기만 하면 된다. key.pem을 와우자의 cacerts에 등록하거나 전달해서는 안 된다.

인증서를 생성하면 해당 도메인의 트래픽이 자동으로 시험 서버에 전달되는가?

아니다. 인증서는 서버의 신원을 표시하고 검증하는 역할만 하며 네트워크 경로를 변경하지 않는다. b.upload.youtube.com의 요청을 PushCap으로 보내려면 송출 장비의 hosts 파일, 내부 DNS 또는 별도의 프록시에서 목적지를 시험 서버의 IP 주소로 연결해야 한다.

인증서가 만료되거나 새로 생성되면 기존 등록을 계속 사용할 수 있는가?

사용할 수 없다. 새로 생성한 인증서는 기존 인증서와 공개 키 및 지문이 다르므로 와우자의 신뢰 저장소에 다시 등록해야 한다. 같은 별칭이 이미 존재한다면 기존 항목을 삭제하거나 다른 별칭을 사용한 뒤 와우자 서비스를 다시 시작한다.

와우자에 인증서가 정상적으로 등록되었는지 어떻게 확인하는가?

와우자가 사용하는 JRE의 keytool -list -cacerts 명령으로 등록한 인증서 별칭과 지문을 확인한다. 저장소의 무결성까지 확인하려면 비밀번호 입력 요청에서 Enter만 누르지 말고 실제 cacerts 비밀번호를 입력해야 한다. 등록 후에는 와우자 서비스를 다시 시작해야 변경 사항이 적용된다.

갱신 내역

  1. 최초 게시
  2. 1차 수정
  3. 2차 수정 및 주소 이전