SharpSRTP 0.2.0
dotnet add package SharpSRTP --version 0.2.0
NuGet\Install-Package SharpSRTP -Version 0.2.0
<PackageReference Include="SharpSRTP" Version="0.2.0" />
<PackageVersion Include="SharpSRTP" Version="0.2.0" />
<PackageReference Include="SharpSRTP" />
paket add SharpSRTP --version 0.2.0
#r "nuget: SharpSRTP, 0.2.0"
#:package SharpSRTP@0.2.0
#addin nuget:?package=SharpSRTP&version=0.2.0
#tool nuget:?package=SharpSRTP&version=0.2.0
SharpSRTP
DTLS, DTLS-SRTP and SRTP/SRTCP client and server written in C#.
Implements the following RFCs:
- The Secure Real-time Transport Protocol (SRTP) RFC3711
- Session Description Protocol (SDP) Security Descriptions for Media Streams RFC4568
- The SEED Cipher Algorithm and Its Use with the Secure Real-Time Transport Protocol (SRTP) RFC5669
- Datagram Transport Layer Security (DTLS) Extension to Establish Keys for the Secure Real-time Transport Protocol (SRTP) RFC5764
- The Use of AES-192 and AES-256 in Secure RTP RFC6188
- Encryption of Header Extensions in the Secure Real-time Transport Protocol (SRTP) RFC6904
- AES-GCM Authenticated Encryption in the Secure Real-time Transport Protocol (SRTP) RFC7714
- The ARIA Algorithm and Its Use with the Secure Real-Time Transport Protocol (SRTP) RFC8269
- Double Encryption Procedures for the Secure Real-Time Transport Protocol (SRTP) RFC8723
SRTP Crypto Suites
Currently implemented SRTP Crypto Suites are:
- AES_CM_128_HMAC_SHA1_80 RFC4568
- AES_CM_128_HMAC_SHA1_32 RFC4568
- F8_128_HMAC_SHA1_80 RFC4568
- SEED_CTR_128_HMAC_SHA1_80 RFC5669
- SEED_128_CCM_80 RFC5669
- SEED_128_GCM_96 RFC5669
- AES_192_CM_HMAC_SHA1_80 RFC6188
- AES_192_CM_HMAC_SHA1_32 RFC6188
- AES_256_CM_HMAC_SHA1_80 RFC6188
- AES_256_CM_HMAC_SHA1_32 RFC6188
- AEAD_AES_128_GCM RFC7714
- AEAD_AES_256_GCM RFC7714
DTLS-SRTP Protection Profiles
Currently implemented DTLS-SRTP protection profiles are:
- SRTP_AES128_CM_HMAC_SHA1_80 RFC5764
- SRTP_AES128_CM_HMAC_SHA1_32 RFC5764
- SRTP_NULL_HMAC_SHA1_80 RFC5764
- SRTP_NULL_HMAC_SHA1_32 RFC5764
- SRTP_AEAD_AES_128_GCM RFC7714
- SRTP_AEAD_AES_256_GCM RFC7714
- DOUBLE_AEAD_AES_128_GCM_AEAD_AES_128_GCM RFC8723
- DOUBLE_AEAD_AES_256_GCM_AEAD_AES_256_GCM RFC8723
- SRTP_ARIA_128_CTR_HMAC_SHA1_80 RFC8269
- SRTP_ARIA_128_CTR_HMAC_SHA1_32 RFC8269
- SRTP_ARIA_256_CTR_HMAC_SHA1_80 RFC8269
- SRTP_ARIA_256_CTR_HMAC_SHA1_32 RFC8269
- SRTP_AEAD_ARIA_128_GCM RFC8269
- SRTP_AEAD_ARIA_256_GCM RFC8269
Thread Safety
SharpSRTP is not thread-safe. If multiple threads need to access the same SRTP context, proper synchronization mechanisms must be implemented by the user.
DTLS
The current DTLS implementation is based upon BouncyCastle and supports DTLS 1.2 only.
DTLS Server
Start with generating the TLS certificate. Self-signed RSA SHA256 certificate can be generated as follows:
bool isRSA = true;
var rsaCertificate = DtlsCertificateUtils.GenerateCertificate("DTLS", DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(30), isRSA);
Create the DTLS server and subscribe the OnHandshakeCompleted event to get notified when a client connects:
DtlsServer server = new DtlsServer(rsaCertificate.Certificate, rsaCertificate.PrivateKey, SignatureAlgorithm.rsa, HashAlgorithm.sha256);
server.OnHandshakeCompleted += (sender, e) =>
{
...
};
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
UdpDatagramTransport udpServerTransport = new UdpDatagramTransport("127.0.0.1:8888", null);
Wait for the client and perform DTLS handshake:
bool isShutdown = false;
while(!isShutdown)
{
DtlsTransport dtlsTransport = server.DoHandshake(
out string error,
udpServerTransport,
() =>
{
return udpServerTransport.RemoteEndPoint.ToString();
},
(remoteEndpoint) =>
{
return new UdpDatagramTransport(null, remoteEndpoint);
});
var session = Task.Run(() =>
{
...
});
}
Receive data from the client:
byte[] buffer = new byte[dtlsTransport.GetReceiveLimit()];
int receivedLength = dtlsTransport.Receive(buffer, 0, buffer.Length, 100);
Send data to the client:
dtlsTransport.Send(buffer, 0, buffer.Length);
To modify the offered crypto suites for the DTLS handshake, simply override GetSupportedCipherSuites and return a different set of crypto suites. To support a different version of DTLS, override GetSupportedVersions and return a different version. Note that as of January 2026, BouncyCastle still does not support DTLS 1.3.
DTLS Client
Start with creating the TLS certificate. Certificate type of the client must match the certificate type on the server, meaning if the server uses RSA certificate, the client has to use RSA certificate as well:
var rsaCertificate = DtlsCertificateUtils.GenerateCertificate("DTLS", DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(30), true);
Create the DTLS client:
DtlsClient client = new DtlsClient(null, rsaCertificate.certificate, rsaCertificate.key, SignatureAlgorithm.rsa, HashAlgorithm.sha256);
Optionally, you can let the client auto-generate the matching certificate:
DtlsClient client = new DtlsClient();
Subscribe for OnHandshakeCompleted:
client.OnHandshakeCompleted += (sender, e) =>
{
...
};
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
UdpDatagramTransport udpServerTransport = new UdpDatagramTransport(null, "127.0.0.1:8888");
Connect the client:
DtlsTransport dtlsTransport = client.DoHandshake(out string error, udpClientTransport);
Receive data to the server:
dtlsTransport.Send(buffer, 0, buffer.Length);
Receive data from the server:
byte[] buffer = new byte[dtlsTransport.GetReceiveLimit()];
int receivedLength = dtlsTransport.Receive(buffer, 0, buffer.Length, 100);
Close the transport:
dtlsTransport.Close();
SRTP
SRTP implementation is designed to take RTP/RTCP and convert it to SRTP/SRTCP while maintaining the SRTP context. RTP/RTSP server and clients are out of the scope of this library, but for a fully working example based upon SharpRTSP please refer to the examples.
Server
Generate a random SRTP master key for AES_CM_128_HMAC_SHA1_80 on the server:
string cryptoSuite = SrtpCryptoSuites.AES_CM_128_HMAC_SHA1_80;
byte[] MKI = null;
SrtpKeys keys = SrtpProtocol.CreateMasterKeys(cryptoSuite, MKI);
Obtain the generated master key + master salt to send it to the client:
byte[] masterKeySalt = keys.MasterKeySalt;
Create a new SRTP context using those keys:
SrtpSessionContext context = SrtpProtocol.CreateSrtpSessionContext(keys);
Client
Create a new SRTP context using existing keys from the server:
string cryptoSuite = SrtpCryptoSuites.AES_CM_128_HMAC_SHA1_80;
byte[] masterKeySalt = ...
byte[] MKI = null;
SrtpKeys keys = SrtpProtocol.CreateMasterKeys(cryptoSuite, MKI, masterKeySalt);
SrtpSessionContext context = SrtpProtocol.CreateSrtpSessionContext(keys);
RTP
To encrypt RTP and create SRTP:
byte[] rtp = ...
byte[] rtpBuffer = new byte[context.CalculateRequiredSrtpPayloadLength(rtp.Length)];
Buffer.BlockCopy(rtp, 0, rtpBuffer, 0, rtp.Length);
context.ProtectRtp(rtpBuffer, rtp.Length, out int length);
byte[] srtp = rtpBuffer.Take(length).ToArray();
To decrypt SRTP and create RTP:
byte[] srtp = ...
context.UnprotectRtp(srtp, srtp.Length, out int length);
byte[] rtp = srtp.Take(length).ToArray();
RTCP
To encrypt RTCP and create SRTCP:
byte[] rtcp = ...
byte[] rtcpBuffer = new byte[context.CalculateRequiredSrtcpPayloadLength(rtcp.Length)];
Buffer.BlockCopy(rtcp, 0, rtcpBuffer, 0, rtcp.Length];
context.ProtectRtcp(rtcpBuffer, rtcp.Length, out int length);
byte[] srtcp = rtcpBuffer.Take(length).ToArray();
To decrypt SRTCP and create RTCP:
byte[] srtcp = ...
context.UnprotectRtcp(srtcp, srtcp.Length, out int length);
byte[] rtcp = srtcp.Take(length).ToArray();
Samples
SRTP samples can be found in the SharpRealtimeStreaming repo.
DTLS-SRTP
DTLS-SRTP uses a modified DTLS client/server with the "use_srtp" extension to negotiate the SRTP encryption parameters and derive the corresponding SRTP keys.
Server
First generate the TLS certificate, this time it will be ECDsa:
bool isRSA = false;
var ecdsaCertificate = DtlsCertificateUtils.GenerateCertificate("WebRTC", DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(30), isRSA);
Create the DTLS-SRTP server:
var server = new DtlsSrtpServer(ecdsaCertificate.Certificate, ecdsaCertificate.PrivateKey, SignatureAlgorithm.ecdsa, HashAlgorithm.sha256);
Subscribe for OnSessionStarted:
server.OnSessionStarted += (sender, e) =>
{
var context = e.Context;
var clientTransport = e.ClientDatagramTransport;
...
};
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
UdpDatagramTransport udpServerTransport = new UdpDatagramTransport("127.0.0.1:8888", null);
Wait for the client and perform DTLS handshake:
bool isShutdown = false;
while(!isShutdown)
{
DtlsTransport dtlsTransport = server.DoHandshake(
out string error,
udpServerTransport,
() =>
{
return udpServerTransport.RemoteEndPoint.ToString();
},
(remoteEndpoint) =>
{
return new UdpDatagramTransport(null, remoteEndpoint);
});
}
After the OnSessionStarted event is executed, you can use the Context to protect/unprotect data and clientTransport to send/receive SRTP.
Client
Generate the TLS certificate, this time it will be ECDsa:
bool isRSA = false;
var ecdsaCertificate = DtlsCertificateUtils.GenerateCertificate("WebRTC", DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(30), isRSA);
Create the DTLS-SRTP client:
var client = new DtlsSrtpClient(ecdsaCertificate.Certificate, ecdsaCertificate.PrivateKey, SignatureAlgorithm.ecdsa, HashAlgorithm.sha256)
Subscribe for OnSessionStarted:
client.OnSessionStarted += (sender, e) =>
{
var context = e.Context;
var clientTransport = e.ClientDatagramTransport;
...
};
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
UdpDatagramTransport udpServerTransport = new UdpDatagramTransport(null, "127.0.0.1:8888");
Connect the client:
DtlsTransport dtlsTransport = client.DoHandshake(out string error, udpClientTransport);
After the OnSessionStarted event is executed, you can use the Context to protect/unprotect data and clientTransport to send/receive SRTP.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8.1
- BouncyCastle.Cryptography (>= 2.6.2)
- System.Memory (>= 4.6.3)
-
.NETStandard 2.0
- BouncyCastle.Cryptography (>= 2.6.2)
- System.Memory (>= 4.6.3)
-
net10.0
- BouncyCastle.Cryptography (>= 2.6.2)
-
net8.0
- BouncyCastle.Cryptography (>= 2.6.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on SharpSRTP:
| Package | Downloads |
|---|---|
|
SharpRTSPServer
Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC. |
|
|
SharpRTSPClient
Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC. |
GitHub repositories
This package is not used by any popular GitHub repositories.