SlideShare a Scribd company logo
Insertable Streams and E2EE in WebRTC: a Janus story
Lorenzo Miniero
ClueCon – Chicago, IL, USA (kinda!)
August 5th 2020
Who am I?
Lorenzo Miniero
• Ph.D @ UniNA
• Chairman @ Meetecho
• Main author of Janus®
Contacts and info
• lorenzo@meetecho.com
• https://twitter.com/elminiero
• https://www.slideshare.net/LorenzoMiniero
• https://soundcloud.com/lminiero
Just a few words on Meetecho
• Co-founded in 2009 as an academic spin-off
• University research efforts brought to the market
• Completely independent from the University
• Focus on real-time multimedia applications
• Strong perspective on standardization and open source
• Several activities
• Consulting services
• Commercial support and Janus licenses
• Streaming of live events (IETF, ACM, etc.)
• Proudly brewed in sunny Napoli, Italy
Home Sweet Home!
WebRTC reference architecture: peer-to-peer
WebRTC reference architecture: peer-to-peer
Involving a server as a peer
Involving a server as a peer
Breaking end-to-end encryption
Many reasons why that may be needed
• Server being a “MITM” is often a feature, actually
• It may need to transcode media
• An MCU even more so! (e.g., FreeSwitch)
• Recordings typically need access to unencrypted media too
• Even when just relaying, access to payload may be sometimes required
• e.g., Simulcast or SVC
• Codec-specific info (e.g., temporal layer) may be in the payload
• RTP headers would still need to be editable
Can you get true E2EE even through a server?
• Short answer: YES!
• Slightly longer answer: it’s not that easy, though...
Many reasons why that may be needed
• Server being a “MITM” is often a feature, actually
• It may need to transcode media
• An MCU even more so! (e.g., FreeSwitch)
• Recordings typically need access to unencrypted media too
• Even when just relaying, access to payload may be sometimes required
• e.g., Simulcast or SVC
• Codec-specific info (e.g., temporal layer) may be in the payload
• RTP headers would still need to be editable
Can you get true E2EE even through a server?
• Short answer: YES!
• Slightly longer answer: it’s not that easy, though...
Many reasons why that may be needed
• Server being a “MITM” is often a feature, actually
• It may need to transcode media
• An MCU even more so! (e.g., FreeSwitch)
• Recordings typically need access to unencrypted media too
• Even when just relaying, access to payload may be sometimes required
• e.g., Simulcast or SVC
• Codec-specific info (e.g., temporal layer) may be in the payload
• RTP headers would still need to be editable
Can you get true E2EE even through a server?
• Short answer: YES!
• Slightly longer answer: it’s not that easy, though...
Many reasons why that may be needed
• Server being a “MITM” is often a feature, actually
• It may need to transcode media
• An MCU even more so! (e.g., FreeSwitch)
• Recordings typically need access to unencrypted media too
• Even when just relaying, access to payload may be sometimes required
• e.g., Simulcast or SVC
• Codec-specific info (e.g., temporal layer) may be in the payload
• RTP headers would still need to be editable
Can you get true E2EE even through a server?
• Short answer: YES!
• Slightly longer answer: it’s not that easy, though...
An excellent talk on the challenges of E2EE!
https://www.youtube.com/watch?v=a0vhHmONWlw
Privacy Enhanced RTP Conferencing (PERC)
https://datatracker.ietf.org/wg/perc/about/
Not very popular among WebRTC developers, though...
https://mailarchive.ietf.org/arch/msg/perc/x1HjohPL6ISuoNj7eE6HEre7O1E/
A simpler approach: PERC “Lite”
PERC Lite and Janus
https://www.meetecho.com/blog/meetecho-and-cosmo-strike-again-perc-lite-integration-in-janus/
PERC Lite and Janus
https://www.meetecho.com/blog/meetecho-and-cosmo-strike-again-perc-lite-integration-in-janus/
Replaying encrypted recordings (“DRM”)
Replaying encrypted recordings (“DRM”)
Enter Insertable Streams!
• New browser API that allows custom processing on WebRTC frames
• Key use case −→ E2EE!
• Works with encoded frames, not individual packets
• [OUT] audio/video frames after they’ve been encoded, but before RTP packetization
• [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization
• Working with frames makes it protocol agnostic
• Today it’s RTP, tomorrow it might be QUIC
Some useful reads
• https://www.meetecho.com/blog/janus-e2ee-sframe/
• https://webrtcbydralex.com/index.php/2020/03/30/
• https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
Enter Insertable Streams!
• New browser API that allows custom processing on WebRTC frames
• Key use case −→ E2EE!
• Works with encoded frames, not individual packets
• [OUT] audio/video frames after they’ve been encoded, but before RTP packetization
• [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization
• Working with frames makes it protocol agnostic
• Today it’s RTP, tomorrow it might be QUIC
Some useful reads
• https://www.meetecho.com/blog/janus-e2ee-sframe/
• https://webrtcbydralex.com/index.php/2020/03/30/
• https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
Enter Insertable Streams!
• New browser API that allows custom processing on WebRTC frames
• Key use case −→ E2EE!
• Works with encoded frames, not individual packets
• [OUT] audio/video frames after they’ve been encoded, but before RTP packetization
• [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization
• Working with frames makes it protocol agnostic
• Today it’s RTP, tomorrow it might be QUIC
Some useful reads
• https://www.meetecho.com/blog/janus-e2ee-sframe/
• https://webrtcbydralex.com/index.php/2020/03/30/
• https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
Enter Insertable Streams!
• New browser API that allows custom processing on WebRTC frames
• Key use case −→ E2EE!
• Works with encoded frames, not individual packets
• [OUT] audio/video frames after they’ve been encoded, but before RTP packetization
• [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization
• Working with frames makes it protocol agnostic
• Today it’s RTP, tomorrow it might be QUIC
Some useful reads
• https://www.meetecho.com/blog/janus-e2ee-sframe/
• https://webrtcbydralex.com/index.php/2020/03/30/
• https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
Insertable Streams workflow
Insertable Streams workflow
A few challenges with this approach
• Encrypted payload may make life harder for SFUs
• Useful info usually available in the payload
• e.g., how to detect if we got a keyframe?
• A few different solutions to this
• Keep the first bytes unencrypted? (where that info is)
• Ad-hoc RTP extensions for metadata (spec on its way!)
• Encrypting the payload may confuse the RTP (de)packetizer
• Each video codec has different rules
• e.g., H.264 uses NALs, which wouldn’t be visible anymore
• Solution more tricky to find, here
• Keep info used for splitting unencrypted? (codec specific)
• Even better, use a global RTP packetization for all codecs (spec coming!)
A few challenges with this approach
• Encrypted payload may make life harder for SFUs
• Useful info usually available in the payload
• e.g., how to detect if we got a keyframe?
• A few different solutions to this
• Keep the first bytes unencrypted? (where that info is)
• Ad-hoc RTP extensions for metadata (spec on its way!)
• Encrypting the payload may confuse the RTP (de)packetizer
• Each video codec has different rules
• e.g., H.264 uses NALs, which wouldn’t be visible anymore
• Solution more tricky to find, here
• Keep info used for splitting unencrypted? (codec specific)
• Even better, use a global RTP packetization for all codecs (spec coming!)
A few challenges with this approach
• Encrypted payload may make life harder for SFUs
• Useful info usually available in the payload
• e.g., how to detect if we got a keyframe?
• A few different solutions to this
• Keep the first bytes unencrypted? (where that info is)
• Ad-hoc RTP extensions for metadata (spec on its way!)
• Encrypting the payload may confuse the RTP (de)packetizer
• Each video codec has different rules
• e.g., H.264 uses NALs, which wouldn’t be visible anymore
• Solution more tricky to find, here
• Keep info used for splitting unencrypted? (codec specific)
• Even better, use a global RTP packetization for all codecs (spec coming!)
A few challenges with this approach
• Encrypted payload may make life harder for SFUs
• Useful info usually available in the payload
• e.g., how to detect if we got a keyframe?
• A few different solutions to this
• Keep the first bytes unencrypted? (where that info is)
• Ad-hoc RTP extensions for metadata (spec on its way!)
• Encrypting the payload may confuse the RTP (de)packetizer
• Each video codec has different rules
• e.g., H.264 uses NALs, which wouldn’t be visible anymore
• Solution more tricky to find, here
• Keep info used for splitting unencrypted? (codec specific)
• Even better, use a global RTP packetization for all codecs (spec coming!)
Enabling Insertable Streams
pc = new RTCPeerConnection({
encodedInsertableStreams: true,
forceEncodedAudioInsertableStreams: true,
forceEncodedVideoInsertableStreams: true
});
Adding a Sender Trasform
senderTransform = new TransformStream({
start() {
// Called on startup.
},
transform(chunk, controller) {
// Frame encoded, edit payload and return it
[..]
controller.enqueue(chunk);
},
flush() {
// Called when the stream is about to be closed
}
});
sender = pc.addTrack(track, stream)
senderStreams = sender.createEncodedVideoStreams();
senderStreams.readableStream
.pipeThrough(senderTransform)
.pipeTo(senderStreams.writableStream);
Adding a Receiver Trasform as well
receiverTransform = new TransformStream({
start() {
// Called on startup.
},
transform(chunk, controller) {
// Received frame, edit payload and return it
[..]
controller.enqueue(chunk);
},
flush() {
// Called when the stream is about to be closed
}
});
pc.ontrack = function(event) {
[..]
receiverStreams = event.receiver.createEncodedVideoStreams();
receiverStreams.readableStream
.pipeThrough(receiverTransform)
.pipeTo(receiverStreams.writableStream);
}
Integrated in janus.js a few weeks ago
echotest.createOffer({
media: { audio: true, video: true },
senderTransforms: {
audio: new TransformStream({ .. }),
video: new TransformStream({ .. })
},
receiverTransforms: {
audio: new TransformStream({ .. }),
video: new TransformStream({ .. })
},
[..]
success: function(jsep) {
// Send offer to Janus
}
});
https://github.com/meetecho/janus-gateway/pull/2074
Testing basic E2EE in the Janus demos
https://janus.conf.meetecho.com/e2etest
Testing basic E2EE in the Janus demos
https://janus.conf.meetecho.com/e2etest
A step forward: Secure Frames (SFrame)
• Co-developed by CoSMo and Google
• Used in Google Duo for E2EE for a long time already
• https://cosmosoftware.io/secure-frames-sframes/
• https://www.gstatic.com/duo/papers/duo_e2ee.pdf/
• Recently brought to the IETF as well (presented in DISPATCH @ IETF108)
• https://tools.ietf.org/html/draft-omara-sframe-00
• https://mailarchive.ietf.org/arch/browse/sframe/
• Learned lessons from previous E2EE attempts
• Minimizes overhead and impact on servers and clients
• Works of frames, not packets, so transport agnostic
• Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
A step forward: Secure Frames (SFrame)
• Co-developed by CoSMo and Google
• Used in Google Duo for E2EE for a long time already
• https://cosmosoftware.io/secure-frames-sframes/
• https://www.gstatic.com/duo/papers/duo_e2ee.pdf/
• Recently brought to the IETF as well (presented in DISPATCH @ IETF108)
• https://tools.ietf.org/html/draft-omara-sframe-00
• https://mailarchive.ietf.org/arch/browse/sframe/
• Learned lessons from previous E2EE attempts
• Minimizes overhead and impact on servers and clients
• Works of frames, not packets, so transport agnostic
• Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
A step forward: Secure Frames (SFrame)
• Co-developed by CoSMo and Google
• Used in Google Duo for E2EE for a long time already
• https://cosmosoftware.io/secure-frames-sframes/
• https://www.gstatic.com/duo/papers/duo_e2ee.pdf/
• Recently brought to the IETF as well (presented in DISPATCH @ IETF108)
• https://tools.ietf.org/html/draft-omara-sframe-00
• https://mailarchive.ietf.org/arch/browse/sframe/
• Learned lessons from previous E2EE attempts
• Minimizes overhead and impact on servers and clients
• Works of frames, not packets, so transport agnostic
• Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
A step forward: Secure Frames (SFrame)
A step forward: Secure Frames (SFrame)
SFrame.js: an open source SFrame library
• Pure javascript library implementing SFrame using webcrypto
• Developed by Sergio Garcia Murillo
• https://github.com/medooze/sframe
• Described in detail in a blog post and in the CommCon presentation
• https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc-
f9a83a997d6d
• https://www.youtube.com/watch?v=a0vhHmONWlw
• Basically provides everything except the Key Management System (KMS)
• Which makes sense, that should be up to you anyway!
Helped Sergio testing it while integrating it in janus.js
https://www.meetecho.com/blog/janus-e2ee-sframe/
SFrame.js: an open source SFrame library
• Pure javascript library implementing SFrame using webcrypto
• Developed by Sergio Garcia Murillo
• https://github.com/medooze/sframe
• Described in detail in a blog post and in the CommCon presentation
• https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc-
f9a83a997d6d
• https://www.youtube.com/watch?v=a0vhHmONWlw
• Basically provides everything except the Key Management System (KMS)
• Which makes sense, that should be up to you anyway!
Helped Sergio testing it while integrating it in janus.js
https://www.meetecho.com/blog/janus-e2ee-sframe/
SFrame.js: an open source SFrame library
• Pure javascript library implementing SFrame using webcrypto
• Developed by Sergio Garcia Murillo
• https://github.com/medooze/sframe
• Described in detail in a blog post and in the CommCon presentation
• https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc-
f9a83a997d6d
• https://www.youtube.com/watch?v=a0vhHmONWlw
• Basically provides everything except the Key Management System (KMS)
• Which makes sense, that should be up to you anyway!
Helped Sergio testing it while integrating it in janus.js
https://www.meetecho.com/blog/janus-e2ee-sframe/
SFrame.js: an open source SFrame library
• Pure javascript library implementing SFrame using webcrypto
• Developed by Sergio Garcia Murillo
• https://github.com/medooze/sframe
• Described in detail in a blog post and in the CommCon presentation
• https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc-
f9a83a997d6d
• https://www.youtube.com/watch?v=a0vhHmONWlw
• Basically provides everything except the Key Management System (KMS)
• Which makes sense, that should be up to you anyway!
Helped Sergio testing it while integrating it in janus.js
https://www.meetecho.com/blog/janus-e2ee-sframe/
Integrating SFrame.js in janus.js
import {Janus} from ’./janus.js’;
import {SFrame} from ’./sframe/Client.js’;
...
echotest.createOffer({
media: { audio: true, video: true },
sframe: {
outgoingId: 0,
incomingId: 0,
sharedKey: cryptoKey, // Generated previously
keyPair: keyPair // Generated previously
},
[..]
success: function(jsep) {
// Send offer to Janus
}
});
Integrating SFrame.js in janus.js
if(callbacks.sframe) {
Janus.log("Using SFrame to encrypt media end-to-end:", callbacks.sframe);
config.sframe = callbacks.sframe;
config.sframeClient = await SFrame.createClient(config.sframe.outgoingId, {});
// Sender part
await config.sframeClient.setSenderEncryptionKey(config.sframe.shared);
if(config.sframe.keyPair && config.sframe.keyPair.privateKey) {
await config.sframeClient.setSenderSigningKey(config.sframe.keyPair.privateKey);
}
// Receiver part
if(config.sframe.incomingId !== undefined && config.sframe.incomingId !== null) {
await config.sframeClient.addReceiver(config.sframe.incomingId);
await config.sframeClient.setReceiverEncryptionKey(config.sframe.incomingId,
callbacks.sframe.shared);
if(config.sframe.keyPair && config.sframe.keyPair.publicKey) {
await config.sframeClient.setReceiverVerifyKey(config.sframe.incomingId,
config.sframe.keyPair.publicKey);
}
}
}
Integrating SFrame.js in janus.js
// Have SFrame.js configure the Sender Transform
var sender = config.pc.addTrack(track, stream);
config.sframeClient.encrypt(sender.track.id, sender);
...
// Have SFrame.js configure the Receiver Transform
config.pc.ontrack = function(event) {
[..]
config.sframeClient.decrypt(event.track.id, event.receiver);
[..]
}
Testing SFrame with Janus
https://www.meetecho.com/blog/janus-e2ee-sframe/
Testing SFrame with Janus
https://www.meetecho.com/blog/janus-e2ee-sframe/
Thanks! Questions? Comments?
Get in touch!
• https://twitter.com/elminiero
• https://twitter.com/meetecho
• https://www.meetecho.com

More Related Content

PPTX
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
PPTX
DDT (Demand Driven Techniques)
PDF
Multistream in Janus @ CommCon 2019
PDF
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
PDF
Ndc12 이창희 render_pipeline
PDF
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
PPTX
190119 unreal engine c++ 입문 및 팁
PDF
Ndc2012 최지호 텍스쳐 압축 기법 소개
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
DDT (Demand Driven Techniques)
Multistream in Janus @ CommCon 2019
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
Ndc12 이창희 render_pipeline
심예람, <프로젝트DH> AI 내비게이션 시스템, NDC2018
190119 unreal engine c++ 입문 및 팁
Ndc2012 최지호 텍스쳐 압축 기법 소개

What's hot (20)

PPTX
Umg ,이벤트 바인딩, Invaidation Box
PPTX
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
PDF
One step in the future: CSS variables
PDF
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
PDF
[Kgc2012] deferred forward 이창희
PDF
AEM - A Collection of developer friendly tools
PDF
Best Practices for a Complete Postgres Enterprise Architecture Setup
 
PPTX
Virtualization technology for security
PPTX
High Dynamic Range color grading and display in Frostbite
PDF
stm32-usb-c-pd-solutions-presentation.pdf
PDF
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
PDF
Brdf기반 사전정의 스킨 셰이더
PPTX
Local SQLite Database with Node for beginners
PDF
Penner pre-integrated skin rendering (siggraph 2011 advances in real-time r...
PPTX
Git workflows
PDF
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
PPTX
Subway 1
PDF
[NHN_NEXT] 게임 휴먼 프로젝트 CI + GitHub 세팅 방법
PPTX
Next-generation MMORPG service architecture
PDF
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
Umg ,이벤트 바인딩, Invaidation Box
GDC Europe 2014: Unreal Engine 4 for Programmers - Lessons Learned & Things t...
One step in the future: CSS variables
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
[Kgc2012] deferred forward 이창희
AEM - A Collection of developer friendly tools
Best Practices for a Complete Postgres Enterprise Architecture Setup
 
Virtualization technology for security
High Dynamic Range color grading and display in Frostbite
stm32-usb-c-pd-solutions-presentation.pdf
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
Brdf기반 사전정의 스킨 셰이더
Local SQLite Database with Node for beginners
Penner pre-integrated skin rendering (siggraph 2011 advances in real-time r...
Git workflows
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017
Subway 1
[NHN_NEXT] 게임 휴먼 프로젝트 CI + GitHub 세팅 방법
Next-generation MMORPG service architecture
[IGC 2017] 아마존 구승모 - 게임 엔진으로 서버 제작 및 운영까지
Ad

Similar to Insertable Streams and E2EE @ ClueCon2020 (20)

PDF
WebRTC and SIP not just audio and video @ OpenSIPS 2024
PDF
WebRTC Broadcasting @ TADSummit 2023
PDF
WHIP WebRTC Broadcasting @ FOSDEM 2022
PDF
Fuzzing Janus @ IPTComm 2019
PDF
Janus Workshop pt.2 @ ClueCon 2021
PDF
Janus/SIP @ OpenSIPS 2019
PDF
Fuzzing RTC @ Kamailio World 2019
PDF
Janus RTP forwarders @ FOSDEM 2020
PDF
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
PDF
WebRTC security+more @ KamailioWorld 2018
PDF
WebRTC and QUIC: how hard can it be? @ RTC.ON 2024
PPTX
Upperside Webinar - WebRTC Standards Update
PDF
BWE in Janus
PDF
FOSDEM 2020: How can we make WebRTC Easier?
PDF
Scaling WebRTC deployments with multicast @ IETF 110 MBONED
PDF
Janus @ WebRTC Meetup Stockholm
PDF
A Progressive Approach to the Past: Ensuring Backwards Compatability Through ...
PDF
Janus + Audio @ Open Source World
PDF
LCA14: LCA14-502: The way to a generic TrustZone® solution
PDF
WHIP and Janus @ IIT-RTC 2021
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC Broadcasting @ TADSummit 2023
WHIP WebRTC Broadcasting @ FOSDEM 2022
Fuzzing Janus @ IPTComm 2019
Janus Workshop pt.2 @ ClueCon 2021
Janus/SIP @ OpenSIPS 2019
Fuzzing RTC @ Kamailio World 2019
Janus RTP forwarders @ FOSDEM 2020
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
WebRTC security+more @ KamailioWorld 2018
WebRTC and QUIC: how hard can it be? @ RTC.ON 2024
Upperside Webinar - WebRTC Standards Update
BWE in Janus
FOSDEM 2020: How can we make WebRTC Easier?
Scaling WebRTC deployments with multicast @ IETF 110 MBONED
Janus @ WebRTC Meetup Stockholm
A Progressive Approach to the Past: Ensuring Backwards Compatability Through ...
Janus + Audio @ Open Source World
LCA14: LCA14-502: The way to a generic TrustZone® solution
WHIP and Janus @ IIT-RTC 2021
Ad

More from Lorenzo Miniero (19)

PDF
Multistream in SIP and NoSIP @ OpenSIPS Summit 2025
PDF
SIP trunking in Janus @ Kamailio World 2024
PDF
Getting AV1/SVC to work in the Janus WebRTC Server
PDF
The challenges of hybrid meetings @ CommCon 2023
PDF
Real-Time Text and WebRTC @ Kamailio World 2023
PDF
Become a rockstar using FOSS!
PDF
Janus SFU cascading @ IIT-RTC 2022
PDF
SIP transfer with Janus/WebRTC @ OpenSIPS 2022
PDF
WebRTC, RED and Janus @ ClueCon21
PDF
Write a SocialTV app @ OpenSIPS 2021
PDF
JamRTC @ Wonder WebRTC unConference
PDF
Janus + NDI @ ClueCon 2021
PDF
Can WebRTC help musicians? @ FOSDEM 2021
PDF
Virtual IETF meetings with WebRTC @ IETF 109 MOPS
PDF
Can SFUs and MCUs be friends @ IIT-RTC 2020
PDF
Janus Workshop @ ClueCon 2020
PDF
Turning live events to virtual with Janus
PDF
Janus workshop @ RTC2019 Beijing
PDF
Simulcast/SVC @ IIT-RTC 2019
Multistream in SIP and NoSIP @ OpenSIPS Summit 2025
SIP trunking in Janus @ Kamailio World 2024
Getting AV1/SVC to work in the Janus WebRTC Server
The challenges of hybrid meetings @ CommCon 2023
Real-Time Text and WebRTC @ Kamailio World 2023
Become a rockstar using FOSS!
Janus SFU cascading @ IIT-RTC 2022
SIP transfer with Janus/WebRTC @ OpenSIPS 2022
WebRTC, RED and Janus @ ClueCon21
Write a SocialTV app @ OpenSIPS 2021
JamRTC @ Wonder WebRTC unConference
Janus + NDI @ ClueCon 2021
Can WebRTC help musicians? @ FOSDEM 2021
Virtual IETF meetings with WebRTC @ IETF 109 MOPS
Can SFUs and MCUs be friends @ IIT-RTC 2020
Janus Workshop @ ClueCon 2020
Turning live events to virtual with Janus
Janus workshop @ RTC2019 Beijing
Simulcast/SVC @ IIT-RTC 2019

Recently uploaded (20)

PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Encapsulation theory and applications.pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Approach and Philosophy of On baking technology
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Electronic commerce courselecture one. Pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
cuic standard and advanced reporting.pdf
PPTX
Cloud computing and distributed systems.
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
A Presentation on Artificial Intelligence
PPT
Teaching material agriculture food technology
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Encapsulation_ Review paper, used for researhc scholars
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
20250228 LYD VKU AI Blended-Learning.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Encapsulation theory and applications.pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
The AUB Centre for AI in Media Proposal.docx
Approach and Philosophy of On baking technology
Programs and apps: productivity, graphics, security and other tools
Electronic commerce courselecture one. Pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
cuic standard and advanced reporting.pdf
Cloud computing and distributed systems.
NewMind AI Weekly Chronicles - August'25-Week II
A Presentation on Artificial Intelligence
Teaching material agriculture food technology
Review of recent advances in non-invasive hemoglobin estimation
Encapsulation_ Review paper, used for researhc scholars

Insertable Streams and E2EE @ ClueCon2020

  • 1. Insertable Streams and E2EE in WebRTC: a Janus story Lorenzo Miniero ClueCon – Chicago, IL, USA (kinda!) August 5th 2020
  • 2. Who am I? Lorenzo Miniero • Ph.D @ UniNA • Chairman @ Meetecho • Main author of Janus® Contacts and info • lorenzo@meetecho.com • https://twitter.com/elminiero • https://www.slideshare.net/LorenzoMiniero • https://soundcloud.com/lminiero
  • 3. Just a few words on Meetecho • Co-founded in 2009 as an academic spin-off • University research efforts brought to the market • Completely independent from the University • Focus on real-time multimedia applications • Strong perspective on standardization and open source • Several activities • Consulting services • Commercial support and Janus licenses • Streaming of live events (IETF, ACM, etc.) • Proudly brewed in sunny Napoli, Italy
  • 7. Involving a server as a peer
  • 8. Involving a server as a peer
  • 10. Many reasons why that may be needed • Server being a “MITM” is often a feature, actually • It may need to transcode media • An MCU even more so! (e.g., FreeSwitch) • Recordings typically need access to unencrypted media too • Even when just relaying, access to payload may be sometimes required • e.g., Simulcast or SVC • Codec-specific info (e.g., temporal layer) may be in the payload • RTP headers would still need to be editable Can you get true E2EE even through a server? • Short answer: YES! • Slightly longer answer: it’s not that easy, though...
  • 11. Many reasons why that may be needed • Server being a “MITM” is often a feature, actually • It may need to transcode media • An MCU even more so! (e.g., FreeSwitch) • Recordings typically need access to unencrypted media too • Even when just relaying, access to payload may be sometimes required • e.g., Simulcast or SVC • Codec-specific info (e.g., temporal layer) may be in the payload • RTP headers would still need to be editable Can you get true E2EE even through a server? • Short answer: YES! • Slightly longer answer: it’s not that easy, though...
  • 12. Many reasons why that may be needed • Server being a “MITM” is often a feature, actually • It may need to transcode media • An MCU even more so! (e.g., FreeSwitch) • Recordings typically need access to unencrypted media too • Even when just relaying, access to payload may be sometimes required • e.g., Simulcast or SVC • Codec-specific info (e.g., temporal layer) may be in the payload • RTP headers would still need to be editable Can you get true E2EE even through a server? • Short answer: YES! • Slightly longer answer: it’s not that easy, though...
  • 13. Many reasons why that may be needed • Server being a “MITM” is often a feature, actually • It may need to transcode media • An MCU even more so! (e.g., FreeSwitch) • Recordings typically need access to unencrypted media too • Even when just relaying, access to payload may be sometimes required • e.g., Simulcast or SVC • Codec-specific info (e.g., temporal layer) may be in the payload • RTP headers would still need to be editable Can you get true E2EE even through a server? • Short answer: YES! • Slightly longer answer: it’s not that easy, though...
  • 14. An excellent talk on the challenges of E2EE! https://www.youtube.com/watch?v=a0vhHmONWlw
  • 15. Privacy Enhanced RTP Conferencing (PERC) https://datatracker.ietf.org/wg/perc/about/
  • 16. Not very popular among WebRTC developers, though... https://mailarchive.ietf.org/arch/msg/perc/x1HjohPL6ISuoNj7eE6HEre7O1E/
  • 17. A simpler approach: PERC “Lite”
  • 18. PERC Lite and Janus https://www.meetecho.com/blog/meetecho-and-cosmo-strike-again-perc-lite-integration-in-janus/
  • 19. PERC Lite and Janus https://www.meetecho.com/blog/meetecho-and-cosmo-strike-again-perc-lite-integration-in-janus/
  • 22. Enter Insertable Streams! • New browser API that allows custom processing on WebRTC frames • Key use case −→ E2EE! • Works with encoded frames, not individual packets • [OUT] audio/video frames after they’ve been encoded, but before RTP packetization • [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization • Working with frames makes it protocol agnostic • Today it’s RTP, tomorrow it might be QUIC Some useful reads • https://www.meetecho.com/blog/janus-e2ee-sframe/ • https://webrtcbydralex.com/index.php/2020/03/30/ • https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
  • 23. Enter Insertable Streams! • New browser API that allows custom processing on WebRTC frames • Key use case −→ E2EE! • Works with encoded frames, not individual packets • [OUT] audio/video frames after they’ve been encoded, but before RTP packetization • [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization • Working with frames makes it protocol agnostic • Today it’s RTP, tomorrow it might be QUIC Some useful reads • https://www.meetecho.com/blog/janus-e2ee-sframe/ • https://webrtcbydralex.com/index.php/2020/03/30/ • https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
  • 24. Enter Insertable Streams! • New browser API that allows custom processing on WebRTC frames • Key use case −→ E2EE! • Works with encoded frames, not individual packets • [OUT] audio/video frames after they’ve been encoded, but before RTP packetization • [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization • Working with frames makes it protocol agnostic • Today it’s RTP, tomorrow it might be QUIC Some useful reads • https://www.meetecho.com/blog/janus-e2ee-sframe/ • https://webrtcbydralex.com/index.php/2020/03/30/ • https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
  • 25. Enter Insertable Streams! • New browser API that allows custom processing on WebRTC frames • Key use case −→ E2EE! • Works with encoded frames, not individual packets • [OUT] audio/video frames after they’ve been encoded, but before RTP packetization • [IN] audio/video frames before they’ve been decoded, but after RTP de-packetization • Working with frames makes it protocol agnostic • Today it’s RTP, tomorrow it might be QUIC Some useful reads • https://www.meetecho.com/blog/janus-e2ee-sframe/ • https://webrtcbydralex.com/index.php/2020/03/30/ • https://webrtchacks.com/true-end-to-end-encryption-with-webrtc-insertable-streams/
  • 28. A few challenges with this approach • Encrypted payload may make life harder for SFUs • Useful info usually available in the payload • e.g., how to detect if we got a keyframe? • A few different solutions to this • Keep the first bytes unencrypted? (where that info is) • Ad-hoc RTP extensions for metadata (spec on its way!) • Encrypting the payload may confuse the RTP (de)packetizer • Each video codec has different rules • e.g., H.264 uses NALs, which wouldn’t be visible anymore • Solution more tricky to find, here • Keep info used for splitting unencrypted? (codec specific) • Even better, use a global RTP packetization for all codecs (spec coming!)
  • 29. A few challenges with this approach • Encrypted payload may make life harder for SFUs • Useful info usually available in the payload • e.g., how to detect if we got a keyframe? • A few different solutions to this • Keep the first bytes unencrypted? (where that info is) • Ad-hoc RTP extensions for metadata (spec on its way!) • Encrypting the payload may confuse the RTP (de)packetizer • Each video codec has different rules • e.g., H.264 uses NALs, which wouldn’t be visible anymore • Solution more tricky to find, here • Keep info used for splitting unencrypted? (codec specific) • Even better, use a global RTP packetization for all codecs (spec coming!)
  • 30. A few challenges with this approach • Encrypted payload may make life harder for SFUs • Useful info usually available in the payload • e.g., how to detect if we got a keyframe? • A few different solutions to this • Keep the first bytes unencrypted? (where that info is) • Ad-hoc RTP extensions for metadata (spec on its way!) • Encrypting the payload may confuse the RTP (de)packetizer • Each video codec has different rules • e.g., H.264 uses NALs, which wouldn’t be visible anymore • Solution more tricky to find, here • Keep info used for splitting unencrypted? (codec specific) • Even better, use a global RTP packetization for all codecs (spec coming!)
  • 31. A few challenges with this approach • Encrypted payload may make life harder for SFUs • Useful info usually available in the payload • e.g., how to detect if we got a keyframe? • A few different solutions to this • Keep the first bytes unencrypted? (where that info is) • Ad-hoc RTP extensions for metadata (spec on its way!) • Encrypting the payload may confuse the RTP (de)packetizer • Each video codec has different rules • e.g., H.264 uses NALs, which wouldn’t be visible anymore • Solution more tricky to find, here • Keep info used for splitting unencrypted? (codec specific) • Even better, use a global RTP packetization for all codecs (spec coming!)
  • 32. Enabling Insertable Streams pc = new RTCPeerConnection({ encodedInsertableStreams: true, forceEncodedAudioInsertableStreams: true, forceEncodedVideoInsertableStreams: true });
  • 33. Adding a Sender Trasform senderTransform = new TransformStream({ start() { // Called on startup. }, transform(chunk, controller) { // Frame encoded, edit payload and return it [..] controller.enqueue(chunk); }, flush() { // Called when the stream is about to be closed } }); sender = pc.addTrack(track, stream) senderStreams = sender.createEncodedVideoStreams(); senderStreams.readableStream .pipeThrough(senderTransform) .pipeTo(senderStreams.writableStream);
  • 34. Adding a Receiver Trasform as well receiverTransform = new TransformStream({ start() { // Called on startup. }, transform(chunk, controller) { // Received frame, edit payload and return it [..] controller.enqueue(chunk); }, flush() { // Called when the stream is about to be closed } }); pc.ontrack = function(event) { [..] receiverStreams = event.receiver.createEncodedVideoStreams(); receiverStreams.readableStream .pipeThrough(receiverTransform) .pipeTo(receiverStreams.writableStream); }
  • 35. Integrated in janus.js a few weeks ago echotest.createOffer({ media: { audio: true, video: true }, senderTransforms: { audio: new TransformStream({ .. }), video: new TransformStream({ .. }) }, receiverTransforms: { audio: new TransformStream({ .. }), video: new TransformStream({ .. }) }, [..] success: function(jsep) { // Send offer to Janus } }); https://github.com/meetecho/janus-gateway/pull/2074
  • 36. Testing basic E2EE in the Janus demos https://janus.conf.meetecho.com/e2etest
  • 37. Testing basic E2EE in the Janus demos https://janus.conf.meetecho.com/e2etest
  • 38. A step forward: Secure Frames (SFrame) • Co-developed by CoSMo and Google • Used in Google Duo for E2EE for a long time already • https://cosmosoftware.io/secure-frames-sframes/ • https://www.gstatic.com/duo/papers/duo_e2ee.pdf/ • Recently brought to the IETF as well (presented in DISPATCH @ IETF108) • https://tools.ietf.org/html/draft-omara-sframe-00 • https://mailarchive.ietf.org/arch/browse/sframe/ • Learned lessons from previous E2EE attempts • Minimizes overhead and impact on servers and clients • Works of frames, not packets, so transport agnostic • Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
  • 39. A step forward: Secure Frames (SFrame) • Co-developed by CoSMo and Google • Used in Google Duo for E2EE for a long time already • https://cosmosoftware.io/secure-frames-sframes/ • https://www.gstatic.com/duo/papers/duo_e2ee.pdf/ • Recently brought to the IETF as well (presented in DISPATCH @ IETF108) • https://tools.ietf.org/html/draft-omara-sframe-00 • https://mailarchive.ietf.org/arch/browse/sframe/ • Learned lessons from previous E2EE attempts • Minimizes overhead and impact on servers and clients • Works of frames, not packets, so transport agnostic • Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
  • 40. A step forward: Secure Frames (SFrame) • Co-developed by CoSMo and Google • Used in Google Duo for E2EE for a long time already • https://cosmosoftware.io/secure-frames-sframes/ • https://www.gstatic.com/duo/papers/duo_e2ee.pdf/ • Recently brought to the IETF as well (presented in DISPATCH @ IETF108) • https://tools.ietf.org/html/draft-omara-sframe-00 • https://mailarchive.ietf.org/arch/browse/sframe/ • Learned lessons from previous E2EE attempts • Minimizes overhead and impact on servers and clients • Works of frames, not packets, so transport agnostic • Interaction with KMS done out of band, and KMS agnostic (e.g., Signal or MLS)
  • 41. A step forward: Secure Frames (SFrame)
  • 42. A step forward: Secure Frames (SFrame)
  • 43. SFrame.js: an open source SFrame library • Pure javascript library implementing SFrame using webcrypto • Developed by Sergio Garcia Murillo • https://github.com/medooze/sframe • Described in detail in a blog post and in the CommCon presentation • https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc- f9a83a997d6d • https://www.youtube.com/watch?v=a0vhHmONWlw • Basically provides everything except the Key Management System (KMS) • Which makes sense, that should be up to you anyway! Helped Sergio testing it while integrating it in janus.js https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 44. SFrame.js: an open source SFrame library • Pure javascript library implementing SFrame using webcrypto • Developed by Sergio Garcia Murillo • https://github.com/medooze/sframe • Described in detail in a blog post and in the CommCon presentation • https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc- f9a83a997d6d • https://www.youtube.com/watch?v=a0vhHmONWlw • Basically provides everything except the Key Management System (KMS) • Which makes sense, that should be up to you anyway! Helped Sergio testing it while integrating it in janus.js https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 45. SFrame.js: an open source SFrame library • Pure javascript library implementing SFrame using webcrypto • Developed by Sergio Garcia Murillo • https://github.com/medooze/sframe • Described in detail in a blog post and in the CommCon presentation • https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc- f9a83a997d6d • https://www.youtube.com/watch?v=a0vhHmONWlw • Basically provides everything except the Key Management System (KMS) • Which makes sense, that should be up to you anyway! Helped Sergio testing it while integrating it in janus.js https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 46. SFrame.js: an open source SFrame library • Pure javascript library implementing SFrame using webcrypto • Developed by Sergio Garcia Murillo • https://github.com/medooze/sframe • Described in detail in a blog post and in the CommCon presentation • https://medium.com/@medooze/sframe-js-end-to-end-encryption-for-webrtc- f9a83a997d6d • https://www.youtube.com/watch?v=a0vhHmONWlw • Basically provides everything except the Key Management System (KMS) • Which makes sense, that should be up to you anyway! Helped Sergio testing it while integrating it in janus.js https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 47. Integrating SFrame.js in janus.js import {Janus} from ’./janus.js’; import {SFrame} from ’./sframe/Client.js’; ... echotest.createOffer({ media: { audio: true, video: true }, sframe: { outgoingId: 0, incomingId: 0, sharedKey: cryptoKey, // Generated previously keyPair: keyPair // Generated previously }, [..] success: function(jsep) { // Send offer to Janus } });
  • 48. Integrating SFrame.js in janus.js if(callbacks.sframe) { Janus.log("Using SFrame to encrypt media end-to-end:", callbacks.sframe); config.sframe = callbacks.sframe; config.sframeClient = await SFrame.createClient(config.sframe.outgoingId, {}); // Sender part await config.sframeClient.setSenderEncryptionKey(config.sframe.shared); if(config.sframe.keyPair && config.sframe.keyPair.privateKey) { await config.sframeClient.setSenderSigningKey(config.sframe.keyPair.privateKey); } // Receiver part if(config.sframe.incomingId !== undefined && config.sframe.incomingId !== null) { await config.sframeClient.addReceiver(config.sframe.incomingId); await config.sframeClient.setReceiverEncryptionKey(config.sframe.incomingId, callbacks.sframe.shared); if(config.sframe.keyPair && config.sframe.keyPair.publicKey) { await config.sframeClient.setReceiverVerifyKey(config.sframe.incomingId, config.sframe.keyPair.publicKey); } } }
  • 49. Integrating SFrame.js in janus.js // Have SFrame.js configure the Sender Transform var sender = config.pc.addTrack(track, stream); config.sframeClient.encrypt(sender.track.id, sender); ... // Have SFrame.js configure the Receiver Transform config.pc.ontrack = function(event) { [..] config.sframeClient.decrypt(event.track.id, event.receiver); [..] }
  • 50. Testing SFrame with Janus https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 51. Testing SFrame with Janus https://www.meetecho.com/blog/janus-e2ee-sframe/
  • 52. Thanks! Questions? Comments? Get in touch! • https://twitter.com/elminiero • https://twitter.com/meetecho • https://www.meetecho.com