MR.*_*ABC 3 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 []{":"}, 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();
Run Code Online (Sandbox Code Playgroud)
我应该直接将所有内容写入sslStream吗?那浏览器的连接呢proxyClient?我是否还需要包装流,还是可以将所有内容直接写入其中proxyStream?我应该使用AuthenticateAsServer并以某种方式通过AuthenticateAsClient的证书吗?
我看到了,但是没有假证书的AuthenticateAsServer却如何。我可以像在普通流中那样写吗,还是应该考虑些什么?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
IE向我的代理发出CONNECT请求。我的代理看到它的CONNECT请求并获得目标的ip:port(例如,www.hotmail.com:443)。我的代理创建了一个与www.hotmail.com的新TCP连接: 443
到目前为止一切正确。
我的代理从该目标获取SslStream并调用AuthenticateAsClient-这使我的代理与事物的hotmail端建立了安全连接
否。您的代理应该使用您已经拥有的纯文本连接。
然后,我的代理将“ HTTP / 1.0 200”消息发送回浏览器,以表明CONNECT成功。
正确。否则,如果连接失败,则发送回适当的HTTP失败响应。
然后,我的代理从浏览器连接获取SslStream并调用AuthenticateAsServer-为我的代理提供到浏览器端的安全连接
否。您的代理继续使用与浏览器的纯文本连接。
如何在没有伪造证书的情况下进行AuthenticateAsServer?
您根本不需要这样做。
此时,浏览器和上游服务器已准备好执行SSL握手。但是正如您所说,您不想嗅探内容,您自己不必成为SSL端点。您现在要做的就是同时双向复制字节。端点将像您不在时一样进行SSL握手。
| 归档时间: |
|
| 查看次数: |
4521 次 |
| 最近记录: |