-
-
Notifications
You must be signed in to change notification settings - Fork 785
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1338 from pedroSG94/feature/srt-passphrase
Feature/srt passphrase
- Loading branch information
Showing
10 changed files
with
243 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
srt/src/main/java/com/pedro/srt/srt/packets/control/handshake/extension/CipherType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.pedro.srt.srt.packets.control.handshake.extension | ||
|
||
/** | ||
* Created by pedro on 13/11/23. | ||
*/ | ||
enum class CipherType(val value: Int) { | ||
NONE(0), ECB(1), CTR(2), CBC(3), GCM(4) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...src/main/java/com/pedro/srt/srt/packets/control/handshake/extension/KeyMaterialMessage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.pedro.srt.srt.packets.control.handshake.extension | ||
|
||
import com.pedro.srt.srt.packets.data.KeyBasedEncryption | ||
import com.pedro.srt.utils.EncryptInfo | ||
import com.pedro.srt.utils.writeUInt16 | ||
import com.pedro.srt.utils.writeUInt32 | ||
import java.io.ByteArrayOutputStream | ||
|
||
/** | ||
* Created by pedro on 13/11/23. | ||
* | ||
* 0 1 2 3 | ||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* |S| V | PT | Sign | Resv1 | KK| | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | KEKI | | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | Cipher | Auth | SE | Resv2 | | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | Resv3 | SLen/4 | KLen/4 | | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | Salt | | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | | | ||
* + Wrapped Key + | ||
* | | | ||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
* | ||
*/ | ||
class KeyMaterialMessage( | ||
private val encryptInfo: EncryptInfo, | ||
private val streamEncapsulation: StreamEncapsulationType = StreamEncapsulationType.MPEG_TS_SRT | ||
) { | ||
|
||
fun getData(): ByteArray { | ||
val buffer = ByteArrayOutputStream() | ||
val sVersionPacketType = (0 shl 7) or (1 shl 4) or 2 | ||
buffer.write(sVersionPacketType) | ||
//Sign | ||
buffer.write(0x20) | ||
buffer.write(0x29) | ||
val resv1KeyBasedEncryption = 0 shl 2 or encryptInfo.keyBasedEncryption.value | ||
buffer.write(resv1KeyBasedEncryption) | ||
buffer.writeUInt32(0) //keki | ||
buffer.write(encryptInfo.cipher.value) | ||
buffer.write(if (encryptInfo.cipher == CipherType.GCM) 1 else 0) //auth | ||
buffer.write(streamEncapsulation.value) //SE | ||
buffer.write(0) // resv2 | ||
buffer.writeUInt16(0) // resv3 | ||
buffer.write(encryptInfo.salt.size / 4) | ||
buffer.write(encryptInfo.keyLength / 4) | ||
buffer.write(encryptInfo.salt) | ||
buffer.write(encryptInfo.key) | ||
return buffer.toByteArray() | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
...ain/java/com/pedro/srt/srt/packets/control/handshake/extension/StreamEncapsulationType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.pedro.srt.srt.packets.control.handshake.extension | ||
|
||
/** | ||
* Created by pedro on 13/11/23. | ||
*/ | ||
enum class StreamEncapsulationType(val value: Int) { | ||
Unspecified(0), MPEG_TS_UDP(1), MPEG_TS_SRT(2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.pedro.srt.utils | ||
|
||
import com.pedro.srt.srt.packets.control.handshake.extension.CipherType | ||
import com.pedro.srt.srt.packets.data.KeyBasedEncryption | ||
|
||
/** | ||
* Created by pedro on 13/11/23. | ||
*/ | ||
data class EncryptInfo( | ||
val keyBasedEncryption: KeyBasedEncryption, | ||
val cipher: CipherType, | ||
val salt: ByteArray, | ||
val key: ByteArray, | ||
val keyLength: Int | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.pedro.srt.utils | ||
|
||
import com.pedro.srt.srt.packets.control.handshake.EncryptionType | ||
import com.pedro.srt.srt.packets.control.handshake.extension.CipherType | ||
import com.pedro.srt.srt.packets.data.KeyBasedEncryption | ||
import java.nio.ByteBuffer | ||
import java.security.SecureRandom | ||
import javax.crypto.Cipher | ||
import javax.crypto.SecretKeyFactory | ||
import javax.crypto.spec.IvParameterSpec | ||
import javax.crypto.spec.PBEKeySpec | ||
import javax.crypto.spec.SecretKeySpec | ||
import kotlin.experimental.xor | ||
|
||
/** | ||
* Created by pedro on 12/11/23. | ||
* Need API 26+ | ||
* | ||
*/ | ||
class EncryptionUtil(val type: EncryptionType, passphrase: String) { | ||
|
||
//only pair is developed, odd is not supported for now | ||
private val keyBasedEncryption = KeyBasedEncryption.PAIR_KEY | ||
private val cipherType = CipherType.CTR | ||
private val salt: ByteArray | ||
private val sek: ByteArray | ||
private val keyLength: Int = when (type) { | ||
EncryptionType.NONE -> 0 | ||
EncryptionType.AES128 -> 16 | ||
EncryptionType.AES192 -> 24 | ||
EncryptionType.AES256 -> 32 | ||
} | ||
private var keyData = byteArrayOf() | ||
|
||
init { | ||
salt = generateSecureRandomBytes(16) | ||
sek = generateSecureRandomBytes(keyLength) | ||
val kek = calculateKEK(passphrase, salt, keyLength) | ||
keyData = wrapKey(kek, sek) | ||
} | ||
|
||
fun encrypt(bytes: ByteArray, sequence: Int): ByteArray { | ||
val ctr = ByteArray(16) | ||
ByteBuffer.wrap(ctr, 10, 4).putInt(sequence) | ||
for (i in 0 until 14) ctr[i] = (ctr[i] xor salt[i]) | ||
|
||
val block = SecretKeySpec(sek, "AES") | ||
val cipher = Cipher.getInstance("AES/CTR/NoPadding") | ||
cipher.init(Cipher.ENCRYPT_MODE, block, IvParameterSpec(ctr)) | ||
return cipher.doFinal(bytes) | ||
} | ||
|
||
fun getEncryptInfo(): EncryptInfo { | ||
return EncryptInfo( | ||
keyBasedEncryption = keyBasedEncryption, | ||
cipher = cipherType, | ||
salt = salt, | ||
key = keyData, | ||
keyLength = keyLength | ||
) | ||
} | ||
|
||
private fun generateSecureRandomBytes(length: Int): ByteArray { | ||
val secureRandom = SecureRandom() | ||
val randomBytes = ByteArray(length) | ||
secureRandom.nextBytes(randomBytes) | ||
return randomBytes | ||
} | ||
|
||
/** | ||
* Wrap key RFC 3394 | ||
*/ | ||
private fun wrapKey(kek: ByteArray, keyToWrap: ByteArray): ByteArray { | ||
val cipher = Cipher.getInstance("AESWrap") | ||
val secretKek = SecretKeySpec(kek, "AES") | ||
cipher.init(Cipher.WRAP_MODE, secretKek) | ||
val secret = SecretKeySpec(keyToWrap, "AES") | ||
return cipher.wrap(secret) | ||
} | ||
|
||
/** | ||
* generate Pbkdf2 key | ||
*/ | ||
private fun calculateKEK(passphrase: String, salt: ByteArray, keyLength: Int): ByteArray { | ||
return SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(PBEKeySpec(passphrase.toCharArray(), salt.sliceArray(8 until salt.size), 2048, keyLength * 8)).encoded | ||
} | ||
} |