Ric*_*ich 32 .net httpwebrequest
我的应用程序(.net 3.5 sp1)使用HttpWebRequest与不同的端点进行通信,有时它使用HTTPS,其中每个托管服务器可能具有不同的安全协议要求,例如TLS或SSL3或其中之一.
通常,服务器可以很好地和愉快地协商/回退SecurityProtocol使用TLS或SSL3,但有些则没有,当.net被设置为TLS或SSL3(我认为默认)那些仅支持SSL3的服务器会导致.net抛出发送错误.
据我所知,.net为ServicePointManager对象提供了一个属性SecurityProtocol,可以将其设置为TLS,SSL3或两者.因此理想情况下,当设置为两个想法是客户端和服务器应该协商使用什么,但如前所述似乎不起作用.
据说你可以设置ServicePointManager.SecurityProtocol = Ssl3但是那些想要使用TLS的端点呢?
我在ServicePointManager和SecurityProtocol中看到的问题是它的静态和应用程序域范围.
那么问题..
我将如何使用不同的SecurityProtocol来使用HttpWebRequest,例如
1)url 1设置为使用TLS | Ssl3(谈判)
2)url 2设置为Ssl3(仅限Ssl3)
fer*_*oze 16
不幸的是,它看起来不像你可以为每个服务点定制.我建议您在MS Connect网站上为此区域提交功能请求.
作为一种肮脏的解决方法,您可以尝试在新的appdomain中执行需要不同安全协议的站点.静态实例是每个appdomain,因此应该为您提供所需的隔离.
k01*_*mb0 13
我遇到了同样的问题并编写了代理类,它在localhost上打开端口并将所有流量转发到指定的host:port.
所以连接就是这样的
[你的代码] --- HTTP ---> [localhost:port上的代理] --- HTTPS ---> [网站]
事实上,它可以用于将任何协议包装到SSL/TLS中,而不仅仅是HTTP
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace System
{
class sslProxy : IDisposable
{
readonly string host;
readonly int port;
readonly TcpListener listener;
readonly SslProtocols sslProtocols;
bool disposed;
static readonly X509CertificateCollection sertCol = new X509CertificateCollection();
public sslProxy(string url, SslProtocols protocols)
{
var uri = new Uri(url);
host = uri.Host;
port = uri.Port;
sslProtocols = protocols;
listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
listener.BeginAcceptTcpClient(onAcceptTcpClient, null);
Proxy = new WebProxy("localhost", (listener.LocalEndpoint as IPEndPoint).Port);
}
public WebProxy Proxy
{
get;
private set;
}
class stBuf
{
public TcpClient tcs;
public TcpClient tcd;
public Stream sts;
public Stream std;
public byte[] buf;
public stBuf dup;
}
void onAcceptTcpClient(IAsyncResult ar)
{
if (disposed) return;
var tcl = listener.EndAcceptTcpClient(ar);
TcpClient tcr = null;
try
{
listener.BeginAcceptTcpClient(onAcceptTcpClient, null);
var nsl = tcl.GetStream();
tcr = new TcpClient(host, port);
Stream nsr = tcr.GetStream();
if (sslProtocols != SslProtocols.None)
{
var sss = new SslStream(nsr, true);
sss.AuthenticateAsClient(host, sertCol, sslProtocols, false);
nsr = sss;
} // if
var sts = new stBuf() { tcs = tcl, sts = nsl, tcd = tcr, std = nsr, buf = new byte[tcl.ReceiveBufferSize] };
var std = new stBuf() { tcs = tcr, sts = nsr, tcd = tcl, std = nsl, buf = new byte[tcr.ReceiveBufferSize] };
sts.dup = std;
std.dup = sts;
nsl.BeginRead(sts.buf, 0, sts.buf.Length, onReceive, sts);
nsr.BeginRead(std.buf, 0, std.buf.Length, onReceive, std);
} // try
catch
{
tcl.Close();
if (tcr != null) tcr.Close();
} // catch
}
void close(stBuf st)
{
var dup = st.dup;
if (dup != null)
{
dup.dup = st.dup = null;
st.sts.Dispose();
st.std.Dispose();
} // if
}
void onReceive(IAsyncResult ar)
{
var st = ar.AsyncState as stBuf;
try
{
if (!(st.dup != null && st.tcs.Connected && st.sts.CanRead && !disposed)) { close(st); return; };
var n = st.sts.EndRead(ar);
if (!(n > 0 && st.tcd.Connected && st.std.CanWrite)) { close(st); return; };
st.std.Write(st.buf, 0, n);
if (!(st.tcs.Connected && st.tcd.Connected && st.sts.CanRead && st.std.CanWrite)) { close(st); return; };
st.sts.BeginRead(st.buf, 0, st.buf.Length, onReceive, st);
} // try
catch
{
close(st);
} // catch
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
listener.Stop();
} // if
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例
// create proxy once and keep it
// note you have to mention :443 port (https default)
// ssl protocols to use (enum can use | or + to have many)
var p = new sslProxy("http://www.google.com:443", SslProtocols.Tls);
// using our connections
for (int i=0; i<5; i++)
{
// url here goes without https just http
var rq = HttpWebRequest.CreateHttp("http://www.google.com/") as HttpWebRequest;
// specify that we are connecting via proxy
rq.Proxy = p.Proxy;
var rs = rq.GetResponse() as HttpWebResponse;
var r = new StreamReader(rs.GetResponseStream()).ReadToEnd();
rs.Dispose();
} // for
// just dispose proxy once done
p.Dispose();
Run Code Online (Sandbox Code Playgroud)
j.v*_*.v. 10
在我们的一些供应商停止对ssl3的支持而其他供应商专门使用它之后,我们的系统中出现了许多问题,这些问题可以通过这个问题的功能来解决.但六年后,我们仍然没有内置机制来实现这一目标.我们的解决方法是明确定义支持所有方案的安全协议,如下所示:
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3
| System.Net.SecurityProtocolType.Tls12
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
38397 次 |
最近记录: |