{"id":7,"date":"2025-08-27T10:10:35","date_gmt":"2025-08-27T10:10:35","guid":{"rendered":"https:\/\/www.decteng.com\/en\/?p=7"},"modified":"2025-08-28T10:06:11","modified_gmt":"2025-08-28T01:06:11","slug":"wowza-https-certificate-for-hls-push-debug-python","status":"publish","type":"post","link":"https:\/\/www.decteng.com\/en\/wowza-https-certificate-for-hls-push-debug-python\/","title":{"rendered":"Apply a Self-Signed HTTPS Certificate to Wowza Streaming Engine for HLS PUSH"},"content":{"rendered":"\n<section>\n<h2>HLS and https certificate<\/h2>\n<p><dfn>HLS(HTTP Live Streaming)<\/dfn>uses the HTTP(HyperText Transfer Protocol) to transfer video files and playlists which describes how to play the video files.<\/p>\n<p>HTTP has been used since the early Internet, but it has security problems because data can be stolen or changed during transmission. To address this issue, the <dfn>HTTPS<\/dfn> was introduced and it became the standard method of data transmission on the Internet in these days. HTTPS validates the target hosts with the <strong>certificate<\/strong> and encrypts the data with <strong>key<\/strong> to enhance transmission security.<\/p>\n<p>The problem is, this kind of security measure can be very helpful in real service enviroments, but become an obstacle in <a href=\"https:\/\/www.decteng.com\/en\/obs-youtube-hls-push-stream-capture-to-debug-pushcap\/\" title=\"OBS HLS PUSH stream capture\" hreflang=\"en\">development environments<\/a> that has no trusted certificate. So, This requires that generate a certificate and allow streaming softwares like <code>OBS<\/code> or <code>Wowza Streaming Engine<\/code> to trust it.<\/p>\n<p>This article explains how to apply a self-signed certificate to streaming software, like Wowza Streaming Engine or OBS, to push HLS streams to a private receiving server such as PushCap.<\/p>\n<\/section>\n\n<section>\n<h2>Generate a certificate using Python<\/h2>\n<h3>Setting up the Environment for Python<\/h3>\n<ol>\n<li><strong>Install Python<\/strong><p>This script is written in Python. Before proceeding, ensure Python is installed on the PC that will act as the server. If needed, consult a <a href=\"https:\/\/realpython.com\/installing-python\/\" title=\"How to Install Python on Your System\" target=\"_blank\" hreflang=\"en\" rel=\"noopener\">guide<\/a> on how to install Python. <\/li>\n<li><strong>Install required package<\/strong><p>Install <code>cryptography<\/code> package to execute the script using the following command.<\/p><code class=\"line\">py -m pip install cryptography<\/code><\/li>\n<li><strong>Create script file<\/strong><p>Create <code>GenCert.py<\/code> file in any directory you want, and copy the following script into the file.<\/p>\n<pre><code>from cryptography import x509\nfrom cryptography.x509.oid import NameOID\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import rsa\nfrom cryptography.hazmat.primitives import serialization\nimport datetime\n\n# Enter domain name here. This is the address will use in streaming software.\ndomain_name = u\"b.upload.youtube.com\"\n\n# 1. Key generate\nkey = rsa.generate_private_key(\n    public_exponent=65537,\n    key_size=2048,\n)\n\n# 2. Key save to key.pem\nwith open(\"key.pem\", \"wb\") as f:\n    f.write(key.private_bytes(\n        encoding=serialization.Encoding.PEM,\n        format=serialization.PrivateFormat.TraditionalOpenSSL,\n        encryption_algorithm=serialization.NoEncryption(),\n    ))\n\n# 3. Certificate information\nsubject = issuer = x509.Name([\n    x509.NameAttribute(NameOID.COUNTRY_NAME, u\"KR\"),\n    x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u\"Gyeonggi-do\"),\n    x509.NameAttribute(NameOID.LOCALITY_NAME, u\"Hanam-si\"),\n    x509.NameAttribute(NameOID.ORGANIZATION_NAME, u\"DectENG\"),\n    x509.NameAttribute(NameOID.COMMON_NAME, domain_name),\n])\n\n# 4. Sign and generate certificate\ncert = x509.CertificateBuilder().subject_name(\n    subject\n).issuer_name(\n    issuer\n).public_key(\n    key.public_key()\n).serial_number(\n    x509.random_serial_number()\n).not_valid_before(\n    datetime.datetime.now(datetime.timezone.utc)\n).not_valid_after(\n    datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=365)\n).add_extension(\n    x509.SubjectAlternativeName([x509.DNSName(domain_name)]),\n    critical=False,\n).sign(key, hashes.SHA256())\n\n# 5. certificate save to file\nwith open(\"cert.pem\", \"wb\") as f:\n    f.write(cert.public_bytes(serialization.Encoding.PEM))\n\nprint(f\"'{domain_name}'  cert.pem \/ key.pem generated.\")\n<\/code><\/pre>Replace <samp>b.upload.youtube.com<\/samp> to the domain name or IP address you want to use.<\/li><\/ol>\n\n<h3>Generate a certificate file<\/h3>\n<ol>\n<li><strong>Execute the script<\/strong><p>In the console, navigate to the directory where <code>GenCert.py<\/code> is located and run the script. If the message <samp>generated.<\/samp> is displayed as shown below, it means that the encryption key and certificate have been successfully generated.<\/p>\n<pre><samp>Microsoft Windows [Version 10.0.20348.4052]\n(c) Microsoft Corporation. All rights reserved.\nD:\\><kbd>cd HLSWEB<\/kbd>\nD:\\HLSWEB><kbd>py GenCert.py<\/kbd>\n'b.upload.youtube.com' cert.pem \/ key.pem generated.<\/samp><\/pre><\/li>\n<li>Copy <code>cert.pem<\/code> and <code>key.pem<\/code> to to the <code>PushCap.py<\/code> execution directory.<\/li>\n<\/ol>\n<p>If you&#8217;re using streaming software without an additional validation feature, such as <code>OBS<\/code>, It&#8217;s now possible to start HTTPS HLS PUSH streaming.<\/p>\n<\/ol>\n<\/section>\n\n<section>\n<h2>Applying a Private Certificate to Wowza Streaming Engine<\/h2>\n<p>In the case of commercial streaming software such as Wowza Streaming Engine, there is an additional certificate verification process, which prevents the use of self-signed certificates. Therefore, for Wowza Streaming Engine, it is necessary to go through a following procedure that registers the generated certificate as a trusted certificate.<\/p?\n\n<ol><li><strong>Stop Wowza Streaming Engine service<\/strong><\/li>\n<li><strong>Open terminal<\/strong> : Open a console terminal with administrator privileges.<\/li>\n<li><strong>Move to Java tools directory<\/strong><p>Move to the Java tool chain directory that using Wowza Streaming Engine. The default locations will be <code>[Wowza Installation Path]\/jre\/bin<\/code><\/li>\n<li><strong>Certificate registration<\/strong><p>Regist the Certificate file to Wowza Streaming Engine with following command.<\/p>\n<kbd style=\"line\">keytool -importcert -alias \"[name]\" -keystore \"[keystore path]\" -storepass changeit -file \"[Certificate file path]\"<\/kbd>\n<p>\n<dl><dt>[name]<\/dt><dd>The user can choose any name for the certificate to save in Wowza Streaming Engine.<\/dd>\n<dt>[keystore path]<\/dt><dd>The path of JRE certificate storage that using by Wowza Streaming Engine. The default path will be <code>[Wowza Installation Path]\\jre\\lib\\security\\cacerts<\/code><\/dd>\n<dt>[Certificate file path]<\/dt><dd>The path and filename of certificate file (<code>.pem<\/code>) to regist.<\/dd><\/dl><\/li><\/ol>\n<\/p>\n\n<h3>Applying a Certificate to Wowza Streaming Engine Example<\/h3>\n<p>This is an example of applying a private certificate to Wowza Streaming Engine in a Windows system. The environment is as follows.<\/p>\n<dl>\n<dt>Operating System<\/dt><dd>Windows Server 2022<\/dd>\n<dt>Wowza Version<\/dt><dd>4.8.25+2<\/dd>\n<dt>Certificate File Path<\/dt><dd><code>D:\\HLSWEB\\cert.pem<\/code><\/dd>\n<\/dl>\n<ol>\n<li>Open a console window (DOS window) with administrator privileges.<\/li>\n<li><strong>Stop the Wowza Engine Service<\/strong><p><pre><samp>C:\\&gt;<kbd>sc stop WowzaStreamingEngine4825+2<\/kbd>\n\nSERVICE_NAME: WowzaStreamingEngine4825+2\n        TYPE               : 10  WIN32_OWN_PROCESS\n        STATE              : 3  STOP_PENDING\n                                (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)\n        WIN32_EXIT_CODE    : 0  (0x0)\n        SERVICE_EXIT_CODE  : 0  (0x0)\n        CHECKPOINT         : 0x0\n        WAIT_HINT          : 0x7d0<\/samp><\/pre><\/p><\/li>\n<li><strong>Certificate file registration<\/strong><p><pre><samp>C:&gt;Program Files\\Wowza Media Systems\\Wowza Streaming Engine 4.8.25+2\\jre\\bin&gt;<kbd>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\"<\/kbd>\nWarning: use -cacerts option to access cacerts keystore\nOwner: CN=b.upload.youtube.com, O=DectENG, L=Hanam-si, ST=Gyeonggi-do, C=KR\nIssuer: CN=b.upload.youtube.com, O=DectENG, L=Hanam-si, ST=Gyeonggi-do, C=KR\nSerial number: 389c81b7d9e5452c8cbace6436a99aff004376\nValid from: Mon Aug 25 23:34:59 KST 2025 until: Tue Aug 25 23:34:59 KST 2026\nCertificate fingerprints:\n         SHA1: AA:BB:CC:DD:EE:FF:AA:BB:CC:DD:EE:FF:65:33:A0:A8:44:55:C0:54\n         SHA256: AA:BB:CC:DD:EE:FF:AA:BB:CC:DD:EE:FF:GG:AA:BB:CC:DD:EE:25:9E:AD:00:54:DE:D0:AE:52:97:1C:A1:85:59\nSignature algorithm name: SHA256withRSA\nSubject Public Key Algorithm: 2048-bit RSA key\nVersion: 3\n\nExtensions:\n\n#1: ObjectId: 2.5.29.17 Criticality=false\nSubjectAlternativeName [\n  DNSName: b.upload.youtube.com\n]\n\nTrust this certificate? [no]:  <kbd>yes<\/kbd>\nCertificate was added to keystore<\/samp><\/pre><\/li>\n\n<li><strong>Verify Certificate Registration<\/strong>\n<p><pre><samp>C:\\Program Files\\Wowza Media Systems\\Wowza Streaming Engine 4.8.25+2\\jre\\bin><kbd>keytool -list -cacerts<\/kbd>\nEnter keystore password:<kbd>Enter<\/kbd>\n\n*****************  WARNING WARNING WARNING  *****************\n* The integrity of the information stored in your keystore  *\n* has NOT been verified!  In order to verify its integrity, *\n* you must provide your keystore password.                  *\n*****************  WARNING WARNING WARNING  *****************\n\nKeystore type: JKS\nKeystore provider: SUN\n\nYour keystore contains 93 entries\n\n... (omitted) ...\nyoutubelocal, 2025 Aug 26, trustedCertEntry,\nCertificate fingerprint (SHA-256): AA:BB:CC:DD:EE:FF:AA:BB:CC:DD:EE:FF:GG:AA:BB:CC:DD:EE:25:9E:AD:00:54:DE:D0:AE:52:97:1C:A1:85:59\n... (omitted) ...<\/samp><\/pre>\n<p>If a certificate with the registered name (in this example, <samp>youtubelocal<\/samp>) exists as shown above, it means the registration was successful.<\/p><\/li>\n<li><strong>Restart the Wowza Engine Service<\/strong><p><pre><samp>C:\\&gt;<kbd>sc start WowzaStreamingEngine4825+2<\/kbd>\nSERVICE_NAME: WowzaStreamingEngine4825+2\n        TYPE               : 10  WIN32_OWN_PROCESS\n        STATE              : 2  START_PENDING\n                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)\n        WIN32_EXIT_CODE    : 0  (0x0)\n        SERVICE_EXIT_CODE  : 0  (0x0)\n        CHECKPOINT         : 0x0\n        WAIT_HINT          : 0x7d0\n        PID                : 4356\n        FLAGS              :<\/samp><\/pre><\/li><\/ol>\n<\/section>\n\n<h2>Concolution<\/h2>\n<p>HLS PUSH receivers like <code>PushCap<\/code> requires a certificate and key for HTTPS communication. Self-generated private certificate can be used like <code>OBS<\/code> that do not perform separate validation.<\/p>\n<p>But some kind of software likes Wowza Streaming Engine, which have internal validation procedures are not accept this kind of certificate until registered as a trusted certificates.<\/p>\n<p>The writer hopes this article provides a little help to readers who need to solve server problems by validate actual streaming data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>HLS PUSH uses the https protocol to transfer data and validate the server using a certificate. This article shows how to create a self-signed certificate via Python and apply it to Wowza Streaming Engine to receive HLS PUSH data on PushCap HLS capture server.<\/p>\n","protected":false},"author":1,"featured_media":10,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[16,17,13,23,14,22,18,15,19,20,21],"class_list":{"0":"post-7","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-ott","8":"tag-development","9":"tag-experience","10":"tag-hls","11":"tag-howto","12":"tag-https","13":"tag-java","14":"tag-live-streaming","15":"tag-obs","16":"tag-system-secure","17":"tag-wowza-streaming-engine","18":"tag-youtube","19":"content-layout-excerpt-thumb"},"_links":{"self":[{"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/posts\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":5,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/posts\/7\/revisions"}],"predecessor-version":[{"id":24,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/posts\/7\/revisions\/24"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/media\/10"}],"wp:attachment":[{"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/media?parent=7"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/categories?post=7"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.decteng.com\/en\/wp-json\/wp\/v2\/tags?post=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}