C# HTTPS代理实现(SSLStream)
我已经编写了一个充当代理服务器的控制台应用程序。现在我也想实现SSL。不喜欢解密任何流量。就像普通的https代理一样。我不知道该怎么办C# HTTPS代理实现(SSLStream),c#,ssl,https,proxy,C#,Ssl,Https,Proxy,我已经编写了一个充当代理服务器的控制台应用程序。现在我也想实现SSL。不喜欢解密任何流量。就像普通的https代理一样。我不知道该怎么办 var host = text.Remove(0, connectText.Length + 1); var hostIndex = host.IndexOf(" ", StringComparison.Ordinal); var hostEntry = host.Remove(hostIndex).Split(new []{":"}, StringSplit
var host = text.Remove(0, connectText.Length + 1);
var hostIndex = host.IndexOf(" ", StringComparison.Ordinal);
var hostEntry = host.Remove(hostIndex).Split(new []{":"}, StringSplitOptions.None);
requestClient.Connect(hostEntry[0], Convert.ToInt32(hostEntry[1]));
requestStream = requestClient.GetStream();
var sslStream = new SslStream(requestStream, false, (x1,x2,x3,x4) => true);
sslStream.AuthenticateAsClient(hostEntry[0]);
const string sslResponse = "HTTP/1.0 200 Connection established\r\n\r\n";
var sslResponseBytes = Encoding.UTF8.GetBytes(sslResponse);
proxyStream.Write(sslResponseBytes, 0, sslResponseBytes.Length);
proxyStream.Flush();
我应该直接将所有内容写入sslStream吗?浏览器连接如何proxyClient
。我是否也需要包装流,还是可以将所有内容直接写入proxyStream
?我应该使用AuthenticateTaserver并以某种方式从AuthenticateTasClient传递证书吗
static void Main(字符串[]args)
{
var tcpServer=newtcplistener(IPAddress.Parse(“127.0.0.1”),8080);
tcpServer.Start();
while(true)
{
var proxyClient=tcpServer.AcceptTcpClient();
var requestClient=new TcpClient();
var proxyStream=proxyClient.GetStream();
NetworkStream requestStream=null;
var bytes=新字节[proxyClient.ReceiveBufferSize];
var hostHeaderAvailable=0;
整数计数;
while(proxyStream.DataAvailable)
{
count=proxyStream.Read(字节,0,字节.长度);
如果(hostHeaderAvailable==0)
{
var text=Encoding.UTF8.GetString(字节);
常量字符串connectText=“connect”;
常量字符串hostText=“主机:”;
//HTTPS尚未完全实现
if(text.ToLower().StartsWith(connectText))
{
var host=text.Remove(0,connectText.Length+1);
var hostIndex=host.IndexOf(“,StringComparison.Ordinal);
var hostEntry=host.Remove(hostIndex.Split)(新[]{:“},StringSplitOptions.None);
requestClient.Connect(hostEntry[0],Convert.ToInt32(hostEntry[1]);
requestStream=requestClient.GetStream();
var sslStream=新的sslStream(requestStream,false,(x1,x2,x3,x4)=>true);
sslStream.client(hostEntry[0]);
const string sslResponse=“HTTP/1.0 200已建立连接\r\n\r\n”;
var sslResponseBytes=Encoding.UTF8.GetBytes(sslResponse);
proxyStream.Write(sslResponseBytes,0,sslResponseBytes.Length);
proxyStream.Flush();
}
//HTTP工作起来很有魅力
否则{
var hostIndex=text.IndexOf(hostText,StringComparison.Ordinal);
如果(主机索引<0)
继续;
var host=text.Remove(0,hostIndex+hostText.Length);
hostIndex=host.IndexOf(“\n”,StringComparison.Ordinal);
如果(主机索引<0)
继续;
host=host.Remove(hostIndex.Replace(“\r”,”);
requestClient.Connect(主机,80);
requestStream=requestClient.GetStream();
}
}
hostHeaderAvailable++;
if(requestClient.Connected){
写入(字节,0,计数);
}
}
如果(!requestClient.Connected){
proxyStream.Close();
proxyClient.Close();
继续;
}
var超时=0;
而(!requestStream.DataAvailable){
如果(超时>12)
打破
睡眠(500);
超时++;
}
while(requestStream.DataAvailable)
{
count=requestStream.Read(字节,0,字节.长度);
proxyStream.Write(字节,0,计数);
}
proxyStream.Close();
proxyClient.Close();
}
}
IE向我的代理发出连接请求
我的代理看到这是一个连接请求,并获取目的地的ip:端口(例如,www.hotmail.com:443)
我的代理创建到www.hotmail.com:443的新TCP连接
到目前为止都是正确的
我的代理从这个目的地获取一个SslStream并调用AuthenticateTaseClient——这使我的代理与hotmail端建立了一个安全的连接
不可以。您的代理应该使用您已有的纯文本连接
然后,我的代理将“HTTP/1.0 200”消息发送回浏览器,表示连接成功
对。或者,如果出现连接故障,则返回相应的HTTP故障响应
然后,我的代理从浏览器连接获取一个SslStream并调用AuthenticateTaserver-为我的代理提供一个到浏览器端的安全连接
否。您的代理继续使用到浏览器的明文连接
如何在没有假证书的情况下认证服务器
你根本不必这么做
此时,浏览器和上游服务器已准备好执行SSL握手。但正如您所说,您不想嗅探内容,您自己也不需要成为SSL端点。您现在所要做的就是同时在两个方向上复制字节。端点将进行SSL握手,就像
static void Main(string[] args)
{
var tcpServer = new TcpListener(IPAddress.Parse("127.0.0.1"), 8080);
tcpServer.Start();
while (true)
{
var proxyClient = tcpServer.AcceptTcpClient();
var requestClient = new TcpClient();
var proxyStream = proxyClient.GetStream();
NetworkStream requestStream = null;
var bytes = new byte[proxyClient.ReceiveBufferSize];
var hostHeaderAvailable = 0;
int count;
while (proxyStream.DataAvailable)
{
count = proxyStream.Read(bytes, 0, bytes.Length);
if (hostHeaderAvailable == 0)
{
var text = Encoding.UTF8.GetString(bytes);
const string connectText = "connect";
const string hostText = "Host: ";
//HTTPS NOT FULLY IMPLEMENTED YET
if (text.ToLower().StartsWith(connectText))
{
var host = text.Remove(0, connectText.Length + 1);
var hostIndex = host.IndexOf(" ", StringComparison.Ordinal);
var hostEntry = host.Remove(hostIndex).Split(new []{":"}, StringSplitOptions.None);
requestClient.Connect(hostEntry[0], Convert.ToInt32(hostEntry[1]));
requestStream = requestClient.GetStream();
var sslStream = new SslStream(requestStream, false, (x1,x2,x3,x4) => true);
sslStream.AuthenticateAsClient(hostEntry[0]);
const string sslResponse = "HTTP/1.0 200 Connection established\r\n\r\n";
var sslResponseBytes = Encoding.UTF8.GetBytes(sslResponse);
proxyStream.Write(sslResponseBytes, 0, sslResponseBytes.Length);
proxyStream.Flush();
}
//HTTP WORKS LIKE A CHARM
else {
var hostIndex = text.IndexOf(hostText, StringComparison.Ordinal);
if (hostIndex < 0)
continue;
var host = text.Remove(0, hostIndex + hostText.Length);
hostIndex = host.IndexOf("\n", StringComparison.Ordinal);
if (hostIndex < 0)
continue;
host = host.Remove(hostIndex).Replace("\r", "");
requestClient.Connect(host, 80);
requestStream = requestClient.GetStream();
}
}
hostHeaderAvailable++;
if (requestClient.Connected) {
requestStream.Write(bytes, 0, count);
}
}
if (!requestClient.Connected) {
proxyStream.Close();
proxyClient.Close();
continue;
}
var timeout = 0;
while (!requestStream.DataAvailable) {
if (timeout > 12)
break;
Thread.Sleep(500);
timeout++;
}
while (requestStream.DataAvailable)
{
count = requestStream.Read(bytes, 0, bytes.Length);
proxyStream.Write(bytes, 0, count);
}
proxyStream.Close();
proxyClient.Close();
}
}