![]() |
VOOZH | about |
dotnet add package SharpSRTP --version 0.5.6
NuGet\Install-Package SharpSRTP -Version 0.5.6
<PackageReference Include="SharpSRTP" Version="0.5.6" />
<PackageVersion Include="SharpSRTP" Version="0.5.6" />Directory.Packages.props
<PackageReference Include="SharpSRTP" />Project file
paket add SharpSRTP --version 0.5.6
#r "nuget: SharpSRTP, 0.5.6"
#:package SharpSRTP@0.5.6
#addin nuget:?package=SharpSRTP&version=0.5.6Install as a Cake Addin
#tool nuget:?package=SharpSRTP&version=0.5.6Install as a Cake Tool
DTLS, DTLS-SRTP and SRTP/SRTCP client and server written in C#.
Implements the following RFCs:
Currently implemented SRTP Crypto Suites are:
Currently implemented DTLS-SRTP protection profiles are:
SharpSRTP is not thread-safe. If multiple threads need to access the same SRTP context, proper synchronization mechanisms must be implemented by the user.
The current DTLS implementation is based upon BouncyCastle and supports DTLS 1.2 only.
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:
DtlsServer server = new DtlsServer(rsaCertificate.Certificate, rsaCertificate.PrivateKey, SignatureAlgorithm.rsa, HashAlgorithm.sha256);
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
EndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 8888);
EndPoint remoteEndpoint = new IPEndPoint(IPAddress.Any, 0);
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
listenSocket.ReceiveTimeout = 0;
listenSocket.Bind(localEndpoint);
Wait for the client and perform DTLS handshake:
UdpTransport transport = null;
byte[] buffer = new byte[UdpTransport.MTU];
bool isShutdown = false;
while(!isShutdown)
{
int length = listenSocket.ReceiveFrom(buffer, ref remoteEndpoint);
if (length > 0)
{
if(transport != null)
{
if (!transport.TryAddToReceiveQueue(buffer.ToArray()))
{
throw new Exception("Receive queue full!");
}
}
else
{
transport = new UdpTransport(listenSocket, remoteEndpoint, UdpTransport.MTU, (t) => { transport = null; });
transport.TryAddToReceiveQueue(buffer.Take(length).ToArray());
var session = Task.Run(() =>
{
DtlsTransport dtlsTransport = server.DoHandshake(transport, out string error, null);
if (dtlsTransport != null)
{
...
}
else
{
transport = null;
}
});
}
}
}
Receive data from the client:
byte[] buffer = new byte[dtlsTransport.GetReceiveLimit()];
int receivedLength = dtlsTransport.Receive(buffer, 0, buffer.Length, 1000);
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.
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();
Create the DTLS transport. Here we will use UDP on localhost, port 8888:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Loopback, 8888);
socket.Connect(remoteEndpoint);
UdpTransport udpClientTransport = new UdpTransport(socket);
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 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.
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);
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);
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();
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();
SRTP samples can be found in the SharpRealtimeStreaming repo.
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.
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 as in the previous example. After the OnSessionStarted event is executed, you can use the Context to protect/unprotect data and clientTransport to send/receive SRTP.
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 as in the previous example. 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 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 is compatible. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 2 NuGet packages that depend on SharpSRTP:
| Package | Downloads |
|---|---|
|
SharpRTSPClient
Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC. |
|
|
SharpRTSPServer
Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.5.6 | 69 | 6/12/2026 |
| 0.5.5 | 96 | 6/7/2026 |
| 0.5.4 | 96 | 6/6/2026 |
| 0.5.3 | 102 | 6/6/2026 |
| 0.5.2 | 450 | 5/20/2026 |
| 0.5.1 | 168 | 4/16/2026 |
| 0.5.0 | 586 | 4/9/2026 |
| 0.4.0 | 171 | 3/20/2026 |
| 0.3.2 | 167 | 3/1/2026 |
| 0.3.1 | 623 | 2/2/2026 |
| 0.3.0 | 441 | 1/19/2026 |
| 0.2.3 | 182 | 1/17/2026 |
| 0.2.2 | 180 | 1/14/2026 |
| 0.2.1 | 174 | 1/13/2026 |
| 0.2.0 | 300 | 1/10/2026 |
| 0.1.0 | 268 | 1/10/2026 |
| 0.0.1 | 292 | 1/4/2026 |