Skip to content

Commit

Permalink
adding srt aes encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroSG94 committed Nov 13, 2023
1 parent 2981a93 commit bfdf242
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.pedro.library.util.streamclient

import com.pedro.srt.srt.SrtClient
import com.pedro.srt.srt.packets.control.handshake.EncryptionType

/**
* Created by pedro on 12/10/23.
Expand All @@ -10,6 +11,13 @@ class SrtStreamClient(
streamClientListener: StreamClientListener?
): StreamBaseClient(streamClientListener) {

/**
* Set passphrase for encrypt. Use empty value to disable it.
*/
fun setPassphrase(passphrase: String, type: EncryptionType) {
srtClient.setPassphrase(passphrase, type)
}

override fun setAuthorization(user: String?, password: String?) {
srtClient.setAuthorization(user, password)
}
Expand Down
12 changes: 11 additions & 1 deletion srt/src/main/java/com/pedro/srt/srt/CommandsManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import com.pedro.srt.srt.packets.DataPacket
import com.pedro.srt.srt.packets.SrtPacket
import com.pedro.srt.srt.packets.control.Ack2
import com.pedro.srt.srt.packets.control.Shutdown
import com.pedro.srt.srt.packets.control.handshake.EncryptionType
import com.pedro.srt.srt.packets.control.handshake.Handshake
import com.pedro.srt.utils.Constants
import com.pedro.srt.utils.EncryptionUtil
import com.pedro.srt.utils.SrtSocket
import com.pedro.srt.utils.TimeUtils
import kotlinx.coroutines.sync.Mutex
Expand Down Expand Up @@ -51,6 +53,13 @@ class CommandsManager {
var host = ""
//Avoid write a packet in middle of other.
private val writeSync = Mutex(locked = false)
private var encryptor: EncryptionUtil? = null

fun setPassphrase(passphrase: String, type: EncryptionType) {
encryptor = if (type == EncryptionType.AES192) throw IllegalArgumentException("AES_192 is unsupported in Android, use AES128 or AES256")
else if (passphrase.isEmpty()) null
else EncryptionUtil(type, passphrase)
}

fun loadStartTs() {
startTS = TimeUtils.getCurrentTimeMicro()
Expand All @@ -63,6 +72,7 @@ class CommandsManager {
@Throws(IOException::class)
suspend fun writeHandshake(socket: SrtSocket?, handshake: Handshake = Handshake()) {
writeSync.withLock {
handshake.encryption = encryptor?.type ?: EncryptionType.NONE
handshake.initialPacketSequence = sequenceNumber
handshake.ipAddress = host
handshake.write(getTs(), 0)
Expand Down Expand Up @@ -91,7 +101,7 @@ class CommandsManager {
sequenceNumber = sequenceNumber++,
packetPosition = packet.packetPosition,
messageNumber = messageNumber++,
payload = packet.buffer,
payload = encryptor?.encrypt(packet.buffer) ?: packet.buffer,
ts = getTs(),
socketId = socketId
)
Expand Down
11 changes: 11 additions & 0 deletions srt/src/main/java/com/pedro/srt/srt/SrtClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.pedro.srt.srt.packets.control.KeepAlive
import com.pedro.srt.srt.packets.control.Nak
import com.pedro.srt.srt.packets.control.PeerError
import com.pedro.srt.srt.packets.control.Shutdown
import com.pedro.srt.srt.packets.control.handshake.EncryptionType
import com.pedro.srt.srt.packets.control.handshake.ExtensionField
import com.pedro.srt.srt.packets.control.handshake.Handshake
import com.pedro.srt.srt.packets.control.handshake.HandshakeType
Expand Down Expand Up @@ -98,6 +99,16 @@ class SrtClient(private val connectCheckerSrt: ConnectCheckerSrt) {
TODO("unimplemented")
}

/**
* Set passphrase for encrypt. Use empty value to disable it.
*/
fun setPassphrase(passphrase: String, type: EncryptionType) {
if (passphrase.length < 10 || passphrase.length > 79) {
throw IllegalArgumentException("passphrase must between 10 and 79 length")
}
commandsManager.setPassphrase(passphrase, type)
}

/**
* Must be called before connect
*/
Expand Down
45 changes: 45 additions & 0 deletions srt/src/main/java/com/pedro/srt/utils/EncryptionUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.pedro.srt.utils

import android.util.Log
import com.pedro.srt.srt.packets.control.handshake.EncryptionType
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.PBEKeySpec

/**
* Created by pedro on 12/11/23.
* Need API 26+
*
*/
class EncryptionUtil(val type: EncryptionType, passphrase: String) {

private val cipher: Cipher
private val iterations = 10_000 //reduce the number for performance but this make it less secure

init {
val keyLength = when (type) {
EncryptionType.NONE -> 0
EncryptionType.AES128 -> 128
EncryptionType.AES192 -> 192
EncryptionType.AES256 -> 256
}
cipher = Cipher.getInstance("AES_$keyLength/CBC/PKCS5PADDING")
val salt = ByteArray(128)
val secureRandom = SecureRandom()
secureRandom.nextBytes(salt)

val spec = PBEKeySpec(passphrase.toCharArray(), salt, iterations, keyLength)
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
val key = factory.generateSecret(spec)
cipher.init(Cipher.ENCRYPT_MODE, key)
}

fun encrypt(bytes: ByteArray): ByteArray {
return cipher.doFinal(bytes)
}

fun encrypt(bytes: ByteArray, offset: Int, length: Int): ByteArray {
return cipher.doFinal(bytes, offset, length)
}
}

0 comments on commit bfdf242

Please sign in to comment.