在我的SIP Sorcery项目中,我正在创建与远程服务器的TLS连接,远程服务器使用证书提供程序。 下面的代码片段连接似乎很好:
static SIPTLSChannel channel_tls;
static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 5061);
static IPEndPoint localEndPoint= new IPEndPoint(IPAddress.Parse("10.0.0.1"), 8080);
static void Main(string[] args)
{
//Certificate file path
string Certificate = Environment.CurrentDirectory + @"\Certificate\myCa.cer";
// Load the certificate into an X509Certificate object.
X509Certificate2 cert = new X509Certificate2(Certificate);
//TLS Channel connection
channel_Tls = new SIPTLSChannel(cert, localEndPoint);
Transport.RemoveSIPChannel(channel_Tcp);
Transport.AddSIPChannel(channel_Tls);
SIPRequest subscribe = new SIPRequest();
.... [setting subscribe parameters] ....
channel_Tls.Send(remoteEP, Encoding.UTF8.GetBytes(subscribe.ToString()), "myCa.cer");
}
但是我如何创建一个私钥来解密我在客户端和服务器之间发送的数据?我可以看到cert.PublicKey不为空。我收到了一些应用程序数据,但由于没有私钥我无法解密,所以我看不出我的客户端和服务器之间出了什么问题......
答案 0 :(得分:1)
无需创建任何其他加密密钥。 TLS连接将加密和解密连接上发送的任何数据。如果你做一个wireshark跟踪,你将能够看到TLS握手,之后所有后续数据包基本上都是随机字节。
为了使SIP TLS通道能够操作您传递给它的文件或证书存储名称,必须包含或访问私钥。如果您提供.cer文件,则从示例的外观来看,很可能没有可用的私钥,SIP TLS通道将无法初始化。通常,您需要一个.pfx或等效文件,它将ceritifcate与私钥结合使用。
同样在发送呼叫中,您不会传入文件ptah,而是应该传递您将接受远程服务器证书的名称。然后,SIP TLS通道将使远程服务器提供的证书名称与您准备接受的证书名称相匹配。
channel_Tls.Send(remoteEP, Encoding.UTF8.GetBytes(subscribe.ToString()), "sip.someserver.com");
<强>更新强>:
我在下面的一条评论中略有误解,只有在客户端尝试连接时SIPTLSChannel上没有可用的私钥时才会抛出异常。如果您只打算使用SIPTLSChannel进行传出连接,那么您不需要私钥(除非另一端的服务器使用在SIP世界中不常见的证书对您进行身份验证)。
关于从SIPTLSChannel获取解密数据的原始问题,正如我之前提到的那样,这一切都发生在幕后。以下是建立与SIP TLS服务器(在本例中为sipsorcery.com)的连接并读取响应的示例。来自服务器的传输请求和响应都通过加密的TLS通道传输,您可以使用wireshark进行验证。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using SIPSorcery.Net;
using SIPSorcery.SIP;
using SIPSorcery.SIP.App;
using SIPSorcery.Sys;
namespace SIPTLS
{
class Program
{
static void Main(string[] args)
{
try
{
var sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine());
sipTransport.SIPTransportRequestReceived += SIPRequestReceived;
sipTransport.SIPTransportResponseReceived += SIPResponseReceived;
X509Certificate2 cert = new X509Certificate2("test-cert.cer");
SIPTLSChannel tlsChannel = new SIPTLSChannel(cert, new IPEndPoint(IPAddress.Any, 5061));
sipTransport.AddSIPChannel(tlsChannel);
var optionsReq = sipTransport.GetRequest(SIPMethodsEnum.OPTIONS, SIPURI.ParseSIPURI("sips:67.222.131.147:5061"));
sipTransport.SendRequest(optionsReq);
}
catch(Exception excp)
{
Console.WriteLine("Exception Main. " + excp);
}
finally
{
Console.WriteLine("Press any key to exit...");
Console.Read();
}
}
private static void SIPRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
{
Console.WriteLine("SIP request received from " + remoteEndPoint + ".");
Console.WriteLine(sipRequest.ToString());
}
private static void SIPResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPResponse sipResponse)
{
Console.WriteLine("SIP response received from " + remoteEndPoint + ".");
Console.WriteLine(sipResponse.ToString());
}
}
}
如果您想要生成自己的证书和私钥,设置MySQL certificates时此页面就是一个很好的指南。
您可以使用浏览器连接到TLS通道正在使用的套接字来测试您的证书是否具有可用于客户端连接的私钥,例如:在上面的示例中,我使用了https://myipaddress.com:5061。