我正在尝试创建一个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.DataAvailable
和ERR_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
。我认为差异就在那里,但我不知道到底是什么。