gpt4 book ai didi

WCF net.tcp 与 ssl

转载 作者:太空宇宙 更新时间:2023-11-03 13:42:41 25 4
gpt4 key购买 nike

嗯,我正在尝试使用 SSL 加密设置一个 net.tcp 连接我有以下类(class)

Wcf 接口(interface):

[ServiceContract()]
public interface IServer
{
[OperationContract]
void Send(string message);
}

服务器:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
class Server : IServer
{
readonly ServiceHost host;

public Server()
{
host = new ServiceHost(this);
host.AddServiceEndpoint(typeof(IServer), Program.GetBinding(), string.Format("net.tcp://localhost:{0}/", 1010));
host.Credentials.ServiceCertificate.Certificate = Program.LoadCert();
host.Open();
}

public void Send(string message)
{
Console.WriteLine(message);
}
}

程序(客户端/服务器):

class Program
{
static ChannelFactory<IServer> channelFactory;
static IServer server;
static RemoteCertificateValidationCallback callback = null;


public const int MaxMessageSize = 1024 * 1024 * 2;
public static Binding GetBinding()
{
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
binding.ReaderQuotas.MaxArrayLength = MaxMessageSize;
binding.ReaderQuotas.MaxBytesPerRead = MaxMessageSize;
binding.MaxBufferSize = MaxMessageSize;
binding.MaxReceivedMessageSize = MaxMessageSize;
binding.MaxBufferPoolSize = binding.MaxBufferSize * 10;
binding.TransactionFlow = false;
binding.ReliableSession.Enabled = false;
binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
return binding;
}


public static X509Certificate2 LoadCert()
{
X509Certificate2 cert = new X509Certificate2();
cert.Import(@"Test2.pfx", "Test", X509KeyStorageFlags.DefaultKeySet);
return cert;
}

static void Main(string[] args)
{
try
{
callback = new RemoteCertificateValidationCallback(ValidateCertificate);
ServicePointManager.ServerCertificateValidationCallback += callback;
Console.WriteLine("[C]lient or [S]erver?");
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.S)
{
StartServer();
}
else if (key.Key == ConsoleKey.C)
{
StartClient();
}
}
finally
{
if (callback != null)
ServicePointManager.ServerCertificateValidationCallback -= callback;
}
}

private static void StartClient()
{
Console.WriteLine("Starting client mode!");
Console.Write("Host:");
string host = Console.ReadLine();
channelFactory = new ChannelFactory<IServer>(GetBinding());

server = channelFactory.CreateChannel(new EndpointAddress(string.Format("net.tcp://{0}:{1}/", host, 1010)));
while (true)
{
Console.Write("Message:");
server.Send(Console.ReadLine());
}
}

private static void StartServer()
{
Console.WriteLine("Starting server mode!");
Server server = new Server();
Console.ReadKey();
GC.KeepAlive(server);
}

public static bool ValidateCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine("ValidateCertificate");
return true;
}
}

当服务器和客户端都在同一台计算机上运行时,这工作正常(但 ValidateCertificate 永远不会像它应该的那样被调用)。

但是如果我在不同的计算机上运行它们,我会在客户端得到以下异常:

Description: The process was terminated due to an unhandled exception. Exception Info: System.ServiceModel.Security.SecurityNegotiationException Stack:

Server stack trace: at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity) at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUpgrade(Stream stream) at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper) at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper) at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout) at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(System.Runtime.Remoting.Messaging.IMessage, System.Runtime.Remoting.Messaging.IMessage) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(System.Runtime.Remoting.Proxies.MessageData ByRef, Int32) at WcfChatTest.Client.Program+IServer.Send(System.String) at WcfChatTest.Client.Program.StartClient() at WcfChatTest.Client.Program.Main(System.String[])

我配置错了什么,为什么在我向它提供证书时调用“WindowsStreamSecurityUpgradeProvider”?

或者如果其他人有一个很好的例子如何在客户端和服务器不在同一域中的情况下在 net.tcp 上获得传输加密?

最佳答案

我解决了问题就行了

server = channelFactory.CreateChannel(new EndpointAddress(string.Format("net.tcp://{0}:{1}/", host, 1010)));

我必须添加一个我用以下代码创建的附加参数

EndpointIdentity.CreateX509CertificateIdentity(certificate)

关于WCF net.tcp 与 ssl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12165389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com