SslStream.AuthenticateAsServer()无限期地阻塞

时间:2018-01-13 12:31:10

标签: c# .net ssl smtp

我正在尝试创建一个SMTPS服务器(主要用于教育目的),但我似乎无法使用TLS对服务器进行身份验证。

我使用Certbot为Debian 8(Jessie)获得了证书。然后我将证书和私钥合并到$ openssl pkcs12 -export -out fullcert.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem的.pfx文件中,然后使用var cert = new X509Certificate2("fullcert.pfx", "password");

加载它

我获得的证书似乎有效,因为cert.ToString(true)似乎正确显示证书的属性,以下代码正确加密/解密字符串

var str = "BeepBoop";
Console.WriteLine("Encrypting... ({0})", str);
var enc = pubkey.Encrypt(System.Text.Encoding.UTF8.GetBytes(str), RSAEncryptionPadding.Pkcs1);
Console.WriteLine("Decrypting...");
var dec = System.Text.Encoding.UTF8.GetString(privkey.Decrypt(enc, RSAEncryptionPadding.Pkcs1));
Console.WriteLine("Finished ({0})", dec);

对不起凌乱的代码

然后我将证书对象传递给另一个对象,该对象在以下代码中使用它:

// PS: the server listens on port 25000
private void HandleClient(TcpClient client)
{
    Console.WriteLine("[==] BeepBoop: connection on " + port);
    //client.ReceiveTimeout = client.SendTimeout = timeout;
    Stream stream = client.GetStream();
    if(Certificate != null)
    {
        var sslStream = new SslStream(stream, false);
        Console.WriteLine("Authenticating...");
        sslStream.AuthenticateAsServer(Certificate, false, SslProtocols.Tls, true);
        Console.WriteLine("Authenticated");
        stream = sslStream;
    }
    Write(stream, ServiceReadyReply);

    // Implementation of SMTP, which does work correctly
}

当我尝试使用this SMTP tool甚至Chrome(通过连接到https://localhost:25000)进行连接时,程序会在sslStream.AuthenticateAsServer(...)上无限期地阻止,直到客户端超时,此时{{1}包含AggregateException的内容被抛出。我尝试过更改参数,但似乎没有任何组合可以使用。

这是我得到的堆栈跟踪:

IOException

PS:我将证书复制到我的MacBook上,但我的Raspberry Pi上发生了完全相同的问题

抛出异常时,属性 at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status) [0x00027] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:606 at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream:ProcessHandshake (Mono.Net.Security.AsyncOperationStatus) at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00000] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs:282 at Mono.Net.Security.AsyncProtocolRequest+<ProcessOperation>d__24.MoveNext () [0x000ff] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs:221 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:447 at Mono.Net.Security.AsyncProtocolRequest+<StartOperation>d__23.MoveNext () [0x00046] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/AsyncProtocolRequest.cs:187 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152 at Mono.Net.Security.MobileAuthenticatedStream.CheckThrow (System.Boolean authSuccessCheck, System.Boolean shutdownCheck) [0x00008] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:91 at Mono.Net.Security.MobileAuthenticatedStream.get_SslProtocol () [0x00011] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:707 at System.Net.Security.SslStream.get_SslProtocol () [0x00000] in /Users/builder/data/lanes/4992/mono-mac-sdk/external/bockbuild/builds/mono-x64/mcs/class/System/System.Net.Security/SslStream.cs:252 为false。 我不知道这些信息是否确实重要,但我想最好提供太多信息而不是太少:)

我对我的具体问题做了很多研究,我发现以下结果似乎与我的问题有关:

此时,我不知道可能出现什么问题。很感谢任何形式的帮助。如果您需要更多信息,我很乐意提供。

更新:当我尝试将Chrome连接到我的服务器时,我得到stream.DataAvailableERR_SSL_PROTOCOL_ERROR AuthenticationException TlsException (也许我在最初调试时忘记将&#39; https://&#39;添加到域名中?我发誓我确实这样做了,但是......)

更新2: MacBook和Raspberry Pi的错误信息不同:以上错误信息来自MacBook,以下是我在RPi上的内容:TlsException.Message = "Unknown Secure Transport error `IllegalParam'."

更新3:好消息!我有一些有用的东西(halleluja)! 我使用以下命令为localhost生成了证书:

Mono.Btls.MonoBtlsException: Ssl error:1000009c:SSL routines:OPENSSL_internal:HTTP_REQUEST

我有两个文件:openssl req -x509 -out localhost.crt -keyout localhost.key \ -newkey rsa:2048 -nodes -sha256 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") localhost.crt。我将这些文件与

结合起来
localhost.key

我只需按两次输入即可为证书生成无密码。 然后,我使用以下代码加载证书:

openssl pkcs12 -export -in localhost.crt -inkey localhost.key -out localhost.pfx

并与

一起使用
certificate = new X509Certificate2("/path/to/localhost.pfx");

然后我连接到https://localhost:8443并得到了经典的旧消息,即我的连接是&#34;不安全&#34;。我继续以任何方式加载页面!万岁!

现在我只需弄清楚其他证书出了什么问题......

更新4:猜猜是什么......它适用于我的其他证书。我一开始不确定出了什么问题,但是我使用的两个命令之间可能存在细微的差别吗?我使用的第一个是

var message = Encoding.UTF8.GetBytes("HTTP/1.1 200 OK\r\n\r\n<h1>Hello world! ( ^-^)/</h1>");
var server = new TcpListener(IPAddress.Any, 8443);
server.Start();
while (true)
{
    var client = server.AcceptTcpClient();
    var stream = new SslStream(client.GetStream(), false);
    stream.AuthenticateAsServer(certificate);
    stream.Write(message, 0, message.Length);
    Thread.Sleep(1000); // Lazy, dirty way to make sure data arrives.
    stream.Close();
}

我用于服务器的是

openssl pkcs12 -export -out fullcert.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem

然后我加载了更新3中描述的证书,它就可以了。这两个命令之间的主要区别在于,第一个使用openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out certificate.pfx ,第二个使用-in cert.pem -certfile chain.pem。我认为差异就在那里,但我不知道到底是什么。

0 个答案:

没有答案