当使用SSLStream到数据的"大"的块(1微克)发送到(已经认证)客户端,分组分段/ dissasembly我看到是FAR使用正常的NetworkStream当大于.
在客户端上使用异步读取(即BeginRead()),重复调用ReadCallback,使用完全相同大小的数据块直到最终数据包(数据的其余部分).对于我发送的数据(它是一个zip文件),段的长度恰好是16363个字节.注意:我的接收缓冲区比这大得多,改变它的大小没有任何影响
据我所知,SSL以不超过18Kb的块加密数据,但由于SSL位于TCP之上,我不认为SSL块的数量与TCP数据包碎片有任何关联吗?
从本质上讲,客户端完全读取数据的时间比使用标准NetworkStream要长20倍(都在localhost上!)
我错过了什么?
编辑:
我开始怀疑SSLStream的接收(或发送)缓冲区大小是有限的.即使我使用同步读取(即SSLStream.Read()),也不再有可用的数据,无论我在尝试读取之前等待多长时间.这与我将接收缓冲区限制为16363字节的行为相同.设置底层NetworkStream的SendBufferSize(在服务器上)和ReceiveBufferSize(在客户端上)无效.
我有一个完全可操作的系统,基于openssl的客户端与openssl服务器交互.每个客户端都有自己的证书,由服务器验证.已使用openssl(X509,pem)生成证书.他们是自签名的.
我现在想要编写一个基于SslStream的测试客户端.我使用了SslStream类文档中的客户端示例.
我的SslStream客户端无法完成握手.stunnel抱怨客户没有发送证书.这在Wireshark中确认(证书长度:握手消息中的0).
我的客户端显示以下异常:
内部异常:收到的消息是意外的或格式错误
这是我加载证书的方式:
X509Certificate cert = new X509Certificate2(filename, password);
X509CertificateCollection certColl = new X509CertificateCollection();
certColl.Add(cert);
Run Code Online (Sandbox Code Playgroud)
我尝试检索证书的各种属性(例如:GetSerialNumberString()).有用.Verify方法返回false.这是我要研究的下一件事.
我如何设置我的SslStream似乎并不重要(相同的结果):
sslStream.AuthenticateAsClient(serverName);
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
new LocalCertificateSelectionCallback(SelectLocalCertificate));
Run Code Online (Sandbox Code Playgroud)
与身份验证相同:
sslStream.AuthenticateAsClient(serverName);
sslStream.AuthenticateAsClient(serverName,
certColl,
SslProtocols.Tls,
true);
Run Code Online (Sandbox Code Playgroud)
SelectLocalCertificate被叫(两次)并返回我的证书.ValidateServerCertificate目前从未被召唤(令我惊讶).
我该怎么调试呢?如果你可以解决我的问题,那就更好了.
UPDATE
我添加了一个函数来执行基于文档中的X509Chain示例的链验证.它显示证书上的各种信息,包括两个有趣的消息:
Element certificate is valid: False
Element error status length: 1
Run Code Online (Sandbox Code Playgroud)
最后,我没有比调用验证时更多的细节.
输出openssl verify cert.pem不报告任何异常.
error 18 at 0 depth lookup:self signed certificate
OK
Run Code Online (Sandbox Code Playgroud)
UPDATE
我从pem中提取了私钥和证书,并生成了cert.pfx(pkcs12).我在个人密钥库中导入cert.pfx没有问题.在我的证书详细信息中,我可以看到一个小图标,表示附加的私钥.
我修改了我的客户端以从我的个人商店检索证书.但我得到了同样的确切失败.
我正在尝试通过SslStream/Tcp客户端连接到服务器.每次我这样做时都会得到一个异常说明:在AuthenticateAsClient线路上从传输流中收到意外的EOF或0字节.
我已启用跟踪日志记录,并在日志中收到以下两个错误:
System.Net信息:0:[12260] SecureChannel#66702757 ::.ctor(hostname = xxx.xx.xx.xxx,#clientCertificates = 0,encryptionPolicy = RequireEncryption)
System.Net信息:0:[12260] SecureChannel#66702757 - 剩下0个客户端证书可供选择.
有人能给我任何关于如何解决这个问题的建议吗?不知道为什么,但如果这有任何区别,它会抛到外部捕获.
try
{
TcpClient client = new TcpClient(_host, _port);
// _stream = client.GetStream();
_stream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null);
_sslReader = new StreamReader(client.GetStream());
try
{
_stream.AuthenticateAsClient(_host);
}
catch (AuthenticationException e)
{
client.Close();
return;
}
HandleConnect();
}
catch (Exception e)
{
_logger.Error(e.BuildExceptionInfo());
}
public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None || sslPolicyErrors == …Run Code Online (Sandbox Code Playgroud) 我正在阅读msdn info articels很长一段时间,但我仍然无法理解它.
基于不需要客户端身份验证的假设:
1.当我打电话时SslStream.AuthenticateAsServer(...),我在服务器端或客户端调用此方法吗?
2.建立SslStream时,只有服务器负责建立SslStream服务器和客户端?
3.如果它只是服务器的责任,是否意味着客户端可以只使用常规send()和recieve()操作而无需自己创建SslStream?
4.客户端是否需要获取证书文件才能验证服务器?
非常感谢你提前,我真的找不到关于这个主题的很多信息,我一直在寻找这个信息很长一段时间..
这个问题是关于解决SslPolicyError.RemoteCertificateNotAvailable错误的。
我开发了一个带有 SSLStream 的 TCP 服务器和另一端的 TCP 客户端。
我使用以下方式验证服务器:
sslStream.BeginAuthenticateAsServer
Run Code Online (Sandbox Code Playgroud)
我通过以下方式对客户端进行身份验证:
sslStream.BeginAuthenticateAsClient
Run Code Online (Sandbox Code Playgroud)
我正在从 加载我的客户端证书Trusted Publishers - Local Machine。
两者都在同一台机器上运行。
我尝试从 .cer 和 .pfx 文件加载客户端证书,而不是从受信任的发布者存储中加载客户端证书。但是服务器的客户端(远程)证书验证器回调因发现SslPolicyErrors错误而失败RemoteCertificateNotAvailable。
如何在异步写入数据到客户端时防止此问题
The BeginWrite method cannot be called when another write operation is pending
Run Code Online (Sandbox Code Playgroud)
mycode的
public async void Send(byte[] buffer)
{
if (buffer == null)
return;
await SslStream.WriteAsync(buffer, 0, buffer.Length);
}
Run Code Online (Sandbox Code Playgroud) 我正在编写一个http自动化框架,我的问题是与经过身份验证的http 安全连接进行通信.在做了一些研究之后,我发现了C#中的SslStream对象,它可以很容易地与我现有的客户端架构集成.问题是; 尽管能够验证我与给定Web服务器的连接,但任何"GET [website] HTTP/1.1"命令似乎只返回标题而不是实际的网页.
我有一种感觉,我没有正确地形成我的网络请求,但我真的不知道.我整个上午一直在做研究,在这个特定的问题上找不到很多资源.这是我项目的代码示例:
private IAsyncResult Request(HttpRequestToken token, ReceiveEvent callback)
{
if (token == null)
throw new Exception("Error. No request information provided. Aborting operation.");
//Setup the TCP Information. (_port is set to 443 for SSL purposes)
var client = new TcpClient(token.Host, _port);
//Get a handle to a networkstream for writing data.
var requestStream = new SslStream(client.GetStream(), false, null);
//Authenticate the request
requestStream.AuthenticateAsClient(token.Host);
//Translate the data.
byte[] sendBuffer = UTF8Encoding.UTF8.GetBytes(token.ToString());
//NOTE: The results of the above …Run Code Online (Sandbox Code Playgroud) 我会清楚地向您提供我的问题,以便您回答我
我有一个客户端 - 服务器(套接字)连接,我使用SslStream保护,因为我知道使用ssl确保我的客户端只会连接到我的服务器
要做到这一点,我必须向我的客户端添加一个功能来验证服务器认证并确保服务器是真实的(我的服务器)
但我真的不知道如何验证我的自签名认证并希望得到你的帮助
此致,并提前致谢
我使用SslStream来构建Web服务器。但是,下面的代码在AuthenticateAsServer时引发异常。
static X509Certificate cert;
protected virtual Stream GetStream(TcpClient client)
{
var ss = new SslStream(client.GetStream(), false);
if (cert == null)
{
cert = X509Certificate2.CreateFromCertFile("test.cer");
}
ss.AuthenticateAsServer(cert, false, System.Security.Authentication.SslProtocols.Tls, true);
return ss;
}
Run Code Online (Sandbox Code Playgroud)
我已经使用X509Certificate2加载cert文件,为什么它仍然引发异常(服务器模式SSL必须使用带有关联私钥的证书)?
cert文件是使用以下命令创建的:
makecert
-pe Exportable private key
-n "CN=localhost" Subject name
-ss my Certificate store name
-sr LocalMachine Certificate store location
-a sha1 Signature algorithm
-sky signature Subject key type is for signature purposes
-r Make a self-signed cert
"test.cer" Output filename
Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用SSL(over SSLStream)的服务器/客户端应用程序,它必须做很多事情(不仅仅是文件接收/发送).目前,它的工作原理是:只有一个连接.我总是从客户端/服务器发送数据SSLStream.WriteLine()并使用它来接收它SSLStream.ReadLine(),因为我可以通过一个连接发送所有信息,我可以从所有线程发送而不会破坏数据.
现在我想实现文件发送和接收.与我的客户端/服务器应用程序中的其他内容一样,每条消息都有一个前缀(如cl_files或sth)和base64编码的内容部分(前缀和内容由|分隔).我实现了这样的文件共享:上传者向接收者发送关于总文件大小的消息,然后上传者通过前缀发送文件的base64编码部分r.
我的问题是文件共享真的很慢.我从localhost到localhost大约20KB/s.我还有另一个问题.如果我增加文件的base64编码部分的大小(这使文件共享更快),前缀r不再出现在接收器上(因此数据无法识别).
我怎样才能让它更快?
任何帮助将不胜感激.
我的(可能很糟糕的)代码是针对客户的:
//its running inside a Thread
FileInfo x = new FileInfo(ThreadInfos.Path);
long size = x.Length; //gets total size
long cursize = 0;
FileStream fs = new FileStream(ThreadInfos.Path, FileMode.Open);
Int16 readblocks = default(Int16);
while (cursize < size) {
byte[] buffer = new byte[4096];
readblocks = fs.Read(buffer, 0, 4096);
ServerConnector.send("r", getBase64FromBytes(buffer));//It sends the encoded Data with the prefix r over SSLStream.WriteLine
cursize = cursize + Convert.ToInt64(readblocks);
ThreadInfos.wait.setvalue((csize …Run Code Online (Sandbox Code Playgroud)