Securing #
Keamanan apa yang dimiliki WebRTC? #
Setiap koneksi WebRTC diautentikasi dan dienkripsi. Anda dapat yakin bahwa pihak ketiga tidak dapat melihat apa yang Anda kirim atau menyisipkan pesan palsu. Anda juga dapat yakin bahwa klien WebRTC yang membuat Session Description adalah yang Anda komunikasikan dengannya.
Sangat penting bahwa tidak ada yang merusak pesan-pesan tersebut. Tidak apa-apa jika pihak ketiga membaca Session Description saat transit. Namun, WebRTC tidak memiliki perlindungan terhadap modifikasinya. Penyerang dapat melakukan serangan man-in-the-middle pada Anda dengan mengubah ICE Candidate dan memperbarui Certificate Fingerprint.
Bagaimana cara kerjanya? #
WebRTC menggunakan dua protokol yang sudah ada sebelumnya, Datagram Transport Layer Security (DTLS) dan Secure Real-time Transport Protocol (SRTP).
DTLS memungkinkan Anda untuk menegosiasikan sesi dan kemudian bertukar data secara aman antara dua peer. Ini adalah saudara dari TLS, teknologi yang sama yang mendukung HTTPS, tetapi DTLS menggunakan UDP alih-alih TCP sebagai transport layer. Itu berarti protokol harus menangani pengiriman yang tidak andal. SRTP dirancang khusus untuk bertukar media secara aman. Ada beberapa optimisasi yang dapat kita lakukan dengan menggunakannya daripada DTLS.
DTLS digunakan terlebih dahulu. Ia melakukan handshake melalui koneksi yang disediakan oleh ICE. DTLS adalah protokol client/server, jadi satu sisi perlu memulai handshake. Peran Client/Server dipilih selama signaling. Selama handshake DTLS, kedua sisi menawarkan sertifikat. Setelah handshake selesai, sertifikat ini dibandingkan dengan hash sertifikat di Session Description. Ini untuk memastikan bahwa handshake terjadi dengan klien WebRTC yang Anda harapkan. Koneksi DTLS kemudian tersedia untuk digunakan untuk komunikasi DataChannel.
Untuk membuat sesi SRTP kita menginisialisasinya menggunakan kunci yang dihasilkan oleh DTLS. SRTP tidak memiliki mekanisme handshake, jadi harus di-bootstrap dengan kunci eksternal. Setelah ini selesai, media dapat dipertukarkan yang dienkripsi menggunakan SRTP!
Security 101 #
Untuk memahami teknologi yang disajikan dalam bab ini, Anda perlu memahami istilah-istilah ini terlebih dahulu. Kriptografi adalah subjek yang rumit, jadi akan bermanfaat untuk berkonsultasi dengan sumber lain juga!
Plaintext dan Ciphertext #
Plaintext adalah input ke cipher. Ciphertext adalah output dari cipher.
Cipher #
Cipher adalah serangkaian langkah yang mengubah plaintext menjadi ciphertext. Cipher kemudian dapat dibalik, sehingga Anda dapat mengubah ciphertext Anda kembali ke plaintext. Cipher biasanya memiliki kunci untuk mengubah perilakunya. Istilah lain untuk ini adalah enkripsi dan dekripsi.
Cipher sederhana adalah ROT13. Setiap huruf dipindahkan 13 karakter ke depan. Untuk membatalkan cipher Anda memindahkan 13 karakter ke belakang. Plaintext HELLO akan menjadi ciphertext URYYB. Dalam hal ini, Cipher adalah ROT, dan kuncinya adalah 13.
Fungsi Hash #
Fungsi hash kriptografi adalah proses satu arah yang menghasilkan digest. Diberikan input, ia menghasilkan output yang sama setiap kali. Penting bahwa outputnya tidak dapat dibalik. Jika Anda memiliki output, Anda seharusnya tidak dapat menentukan inputnya. Hashing berguna ketika Anda ingin mengonfirmasi bahwa pesan tidak dirusak.
Fungsi hash sederhana (walaupun tentu tidak cocok untuk kriptografi nyata) adalah hanya mengambil setiap huruf lainnya. HELLO akan menjadi HLO. Anda tidak dapat mengasumsikan HELLO adalah inputnya, tetapi Anda dapat mengonfirmasi bahwa HELLO akan cocok dengan digest hash.
Kriptografi Public/Private Key #
Kriptografi Public/Private Key menggambarkan jenis cipher yang digunakan DTLS dan SRTP. Dalam sistem ini, Anda memiliki dua kunci, kunci publik dan pribadi. Kunci publik untuk mengenkripsi pesan dan aman untuk dibagikan. Kunci pribadi untuk mendekripsi, dan tidak boleh dibagikan. Ini adalah satu-satunya kunci yang dapat mendekripsi pesan yang dienkripsi dengan kunci publik.
Pertukaran Diffie–Hellman #
Pertukaran Diffie–Hellman memungkinkan dua pengguna yang tidak pernah bertemu sebelumnya untuk membuat shared secret secara aman melalui internet. Pengguna A dapat mengirim rahasia ke Pengguna B tanpa khawatir tentang penyadapan. Ini bergantung pada kesulitan memecahkan masalah logaritma diskrit.
Anda tidak perlu sepenuhnya memahami bagaimana ini bekerja, tetapi ini membantu untuk mengetahui inilah yang membuat handshake DTLS mungkin.
Wikipedia memiliki contoh ini dalam tindakan di sini.
Fungsi Pseudorandom #
Fungsi Pseudorandom (PRF) adalah fungsi yang telah ditentukan untuk menghasilkan nilai yang tampak acak. Ini mungkin mengambil beberapa input dan menghasilkan satu output.
Fungsi Derivasi Kunci #
Derivasi Kunci adalah jenis Fungsi Pseudorandom. Derivasi Kunci adalah fungsi yang digunakan untuk membuat kunci lebih kuat. Satu pola umum adalah key stretching.
Katakanlah Anda diberi kunci yang berukuran 8 byte. Anda dapat menggunakan KDF untuk membuatnya lebih kuat.
Nonce #
Nonce adalah input tambahan ke cipher. Ini digunakan sehingga Anda bisa mendapatkan output yang berbeda dari cipher, bahkan jika Anda mengenkripsi pesan yang sama beberapa kali.
Jika Anda mengenkripsi pesan yang sama 10 kali, cipher akan memberi Anda ciphertext yang sama 10 kali. Dengan menggunakan nonce Anda dapat mendapatkan output yang berbeda, sambil tetap menggunakan kunci yang sama. Penting Anda menggunakan nonce yang berbeda untuk setiap pesan! Jika tidak, itu meniadakan banyak nilainya.
Message Authentication Code #
Message Authentication Code adalah hash yang ditempatkan di akhir pesan. MAC membuktikan bahwa pesan berasal dari pengguna yang Anda harapkan.
Jika Anda tidak menggunakan MAC, penyerang dapat menyisipkan pesan yang tidak valid. Setelah mendekripsi Anda hanya akan mendapatkan sampah karena mereka tidak tahu kuncinya.
Rotasi Kunci #
Rotasi Kunci adalah praktik mengubah kunci Anda pada interval. Ini membuat kunci yang dicuri kurang berdampak. Jika kunci dicuri atau bocor, lebih sedikit data yang dapat didekripsi.
DTLS #
DTLS (Datagram Transport Layer Security) memungkinkan dua peer untuk membangun komunikasi yang aman tanpa konfigurasi yang sudah ada sebelumnya. Bahkan jika seseorang menguping percakapan, mereka tidak akan dapat mendekripsi pesan.
Untuk DTLS Client dan Server berkomunikasi, mereka perlu menyetujui cipher dan kunci. Mereka menentukan nilai-nilai ini dengan melakukan handshake DTLS. Selama handshake, pesan dalam plaintext.
Ketika DTLS Client/Server telah bertukar cukup detail untuk mulai mengenkripsi, ia mengirim Change Cipher Spec. Setelah pesan ini, setiap pesan berikutnya akan dienkripsi!
Format Paket #
Setiap paket DTLS dimulai dengan header.
Content Type #
Anda dapat mengharapkan tipe berikut:
20- Change Cipher Spec22- Handshake23- Application Data
Handshake digunakan untuk bertukar detail untuk memulai sesi. Change Cipher Spec digunakan untuk memberi tahu sisi lain bahwa semuanya akan dienkripsi. Application Data adalah pesan yang dienkripsi.
Version #
Version dapat berupa 0x0000feff (DTLS v1.0) atau 0x0000fefd (DTLS v1.2) tidak ada v1.1.
Epoch #
Epoch dimulai dari 0, tetapi menjadi 1 setelah Change Cipher Spec. Pesan apa pun dengan epoch non-nol dienkripsi.
Sequence Number #
Sequence Number digunakan untuk menjaga pesan tetap teratur. Setiap pesan meningkatkan Sequence Number. Ketika epoch bertambah, Sequence Number dimulai dari awal.
Length dan Payload #
Payload adalah Content Type spesifik. Untuk Application Data, Payload adalah data yang dienkripsi. Untuk Handshake akan berbeda tergantung pada pesannya. Panjang adalah untuk seberapa besar Payload.
Handshake State Machine #
Selama handshake, Client/Server bertukar serangkaian pesan. Pesan-pesan ini dikelompokkan ke dalam flight. Setiap flight mungkin memiliki beberapa pesan di dalamnya (atau hanya satu). Flight tidak lengkap sampai semua pesan dalam flight telah diterima. Kami akan menjelaskan tujuan setiap pesan lebih detail di bawah ini.

ClientHello #
ClientHello adalah pesan awal yang dikirim oleh client. Ini berisi daftar atribut. Atribut ini memberi tahu server cipher dan fitur yang didukung client. Untuk WebRTC ini adalah bagaimana kita memilih SRTP Cipher juga. Ini juga berisi data acak yang akan digunakan untuk menghasilkan kunci untuk sesi.
HelloVerifyRequest #
HelloVerifyRequest dikirim oleh server ke client. Ini untuk memastikan bahwa client bermaksud mengirim permintaan. Client kemudian mengirim ulang ClientHello, tetapi dengan token yang disediakan dalam HelloVerifyRequest.
ServerHello #
ServerHello adalah respons oleh server untuk konfigurasi sesi ini. Ini berisi cipher apa yang akan digunakan ketika sesi ini selesai. Ini juga berisi data acak server.
Certificate #
Certificate berisi sertifikat untuk Client atau Server. Ini digunakan untuk mengidentifikasi secara unik dengan siapa kita berkomunikasi. Setelah handshake selesai, kita akan memastikan sertifikat ini ketika di-hash cocok dengan fingerprint di SessionDescription.
ServerKeyExchange/ClientKeyExchange #
Pesan ini digunakan untuk mengirimkan kunci publik. Saat startup, client dan server keduanya menghasilkan keypair. Setelah handshake nilai-nilai ini akan digunakan untuk menghasilkan Pre-Master Secret.
CertificateRequest #
CertificateRequest dikirim oleh server yang memberi tahu client bahwa ia menginginkan sertifikat. Server dapat Meminta atau Mengharuskan sertifikat.
ServerHelloDone #
ServerHelloDone memberi tahu client bahwa server selesai dengan handshake.
CertificateVerify #
CertificateVerify adalah bagaimana pengirim membuktikan bahwa ia memiliki kunci pribadi yang dikirim dalam pesan Certificate.
ChangeCipherSpec #
ChangeCipherSpec memberi tahu penerima bahwa segala sesuatu yang dikirim setelah pesan ini akan dienkripsi.
Finished #
Finished dienkripsi dan berisi hash dari semua pesan. Ini untuk menegaskan bahwa handshake tidak dirusak.
Pembuatan Kunci #
Setelah Handshake selesai, Anda dapat mulai mengirim data terenkripsi. Cipher dipilih oleh server dan ada di ServerHello. Bagaimana kuncinya dipilih?
Pertama kita menghasilkan Pre-Master Secret. Untuk mendapatkan nilai ini, Diffie–Hellman digunakan pada kunci yang dipertukarkan oleh ServerKeyExchange dan ClientKeyExchange. Detailnya berbeda tergantung pada Cipher yang dipilih.
Selanjutnya Master Secret dihasilkan. Setiap versi DTLS memiliki Pseudorandom function yang ditentukan. Untuk DTLS 1.2 fungsi tersebut mengambil Pre-Master Secret dan nilai acak di ClientHello dan ServerHello.
Output dari menjalankan Pseudorandom Function adalah Master Secret. Master Secret adalah nilai yang digunakan untuk Cipher.
Bertukar ApplicationData #
Kuda beban DTLS adalah ApplicationData. Sekarang kita memiliki cipher yang diinisialisasi, kita dapat mulai mengenkripsi dan mengirimkan nilai.
Pesan ApplicationData menggunakan header DTLS seperti yang dijelaskan sebelumnya. Payload diisi dengan ciphertext. Anda sekarang memiliki Sesi DTLS yang berfungsi dan dapat berkomunikasi dengan aman.
DTLS memiliki banyak fitur menarik lainnya seperti renegosiasi. Mereka tidak digunakan oleh WebRTC, jadi tidak akan dibahas di sini.
SRTP #
SRTP adalah protokol yang dirancang khusus untuk mengenkripsi paket RTP. Untuk memulai sesi SRTP Anda menentukan kunci dan cipher Anda. Tidak seperti DTLS ia tidak memiliki mekanisme handshake. Semua konfigurasi dan kunci dihasilkan selama handshake DTLS.
DTLS menyediakan API khusus untuk mengekspor kunci yang akan digunakan oleh proses lain. Ini didefinisikan dalam RFC 5705.
Pembuatan Sesi #
SRTP mendefinisikan Key Derivation Function yang digunakan pada input. Ketika membuat Sesi SRTP, input dijalankan melalui ini untuk menghasilkan kunci kita untuk SRTP Cipher kita. Setelah ini Anda dapat melanjutkan untuk memproses media.
Bertukar Media #
Setiap paket RTP memiliki SequenceNumber 16 bit. SequenceNumber ini digunakan untuk menjaga paket tetap teratur, seperti Primary Key. Selama panggilan ini akan berputar. SRTP melacaknya dan menyebutnya rollover counter.
Ketika mengenkripsi paket, SRTP menggunakan rollover counter dan sequence number sebagai nonce. Ini untuk memastikan bahwa bahkan jika Anda mengirim data yang sama dua kali, ciphertext akan berbeda. Ini penting untuk mencegah penyerang mengidentifikasi pola atau mencoba serangan replay.