LoginSignup
2
1

More than 5 years have passed since last update.

SRTの暗号化通信を試してみた

Last updated at Posted at 2018-08-29

SRTの暗号化通信を試してみた。
基本的にpassphraseのパラメータを追加し、送信側と受信側でこれが一致していれば通信できる。
key-length も暗号化に関係しているが、これは送信側の設定値が有効になり、受信側は設定が不要のようなのであまり気にしなくてもよいようだ。
VLCでもSRTの通信条件を設定するところでpassphraseを入れることができる。

つまずいたところのメモ。

つまずいたのは以下の2点。

passphraseの長さは10文字以上80文字以下

この範囲を外れているとエラーになる。
しかし、gstreamerではこのソケットプションの設定から帰ってきたエラーを握りつぶしているのでエラーになったことを気付けない。
gstreamerを送信側にして、6文字のpassphrase(短すぎる)を設定しようとしたが暗号化されないという現象で悩んだ。ソースコードを見て気がついた。

ffmpegのバグ

逆にffmpeg(ffplay)ではpassphraseにどんな長さのものを入れてもエラーになる。
passphraseの扱うポインタが間違っていた。
以下のパッチを当てて、正しく動作するようになった。


diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
index 2faf9de580..2290a34435 100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@ -268,7 +268,7 @@ static int libsrt_set_options_pre(URLContext *h, int fd)
     if ((s->mode == SRT_MODE_RENDEZVOUS && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
         (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
         (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
-        (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) ||
+        (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) ||
         (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) ||
         (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
         (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||

追記 (2018.11.12)

このバグはffmpeg 4.1 で解消しました。
https://qiita.com/tetsu_koba/items/cc1ecb9c2f5ae2901aa9

実行例

gstreamerでテストパターンを暗号化して送信する。passphraseは "abcdefgh123456"
key lengthは指定していないのでデフォルトの16(128bit)が使用される。

send_testptn_crypt.sh
#!/bin/sh

gst-launch-1.0 \
  videotestsrc is-live=true pattern=ball \
! video/x-raw,width=640,height=360,framerate=30/1 \
! x264enc tune=zerolatency key-int-max=60 \
! mpegtsmux \
! srtserversink  uri="srt://:7010" passphrase=abcdefgh123456

これを前述のパッチを当ててビルドしたffplayで再生する。

ffplay srt://localhost:7010?passphrase=abcdefgh123456

もしもpassphraseが一致しないときには以下のようなエラーが出て再生できない。

16:44:50.080269/read_thread*E: SRT.c: processSrtMsg_KMRSP: received failure report. STATE: BADSECRET
16:44:50.104531/SRT:RcvQ:worker*E: SRT.c: SECURITY STATUS: BADSECRET - can't decrypt packet.
16:44:50.105470/SRT:RcvQ:worker*E: SRT.c: KMREQ/rcv: (snd) Rx process failure - BADSECRET
16:44:50.105558/SRT:RcvQ:worker*E: SRT.c: SECURITY STATUS: BADSECRET - can't decrypt packet.

関連

新しい映像伝送プロトコルSRTをgstreamerとVLCで試す
ffmpeg 4.0 に入った新しい映像伝送プロトコルSRTを試す
ffmpeg 4.0 をlibsrtを有効にしてビルドする

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1