Linux のTLS 1.3 & OpenSSL 1.1.1 によると、「コンソール アプリ (.NET Core)」プロジェクトで Linux の下で TLS 1.3 を使用できます。
私のコード
using System;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace TestTlsServer {
class Program {
static void Main(string[] args) {
string curdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Console.WriteLine($"my assembly dir====>{curdir}");
SslProtocols protocol = SslProtocols.Tls13;
int port = 5555;
RemoteCertificateValidationCallback certificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
return (true);
};
X509Certificate2 serverCert = new X509Certificate2("server.pfx", "testpass123");
TcpListener server = TcpListener.Create(port);
server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
server.Server.NoDelay = true;
server.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
server.Start();
Task taskServer = Task.Run(() => {
Console.WriteLine("Server started");
while(true) {
TcpClient romoteClient = server.AcceptTcpClient();
Task.Run(() => {
Console.WriteLine($"==============>New Connection from {romoteClient.Client.RemoteEndPoint}");
using(romoteClient) {
using(SslStream sslStreamRomoteClient = new SslStream(romoteClient.GetStream(), false, certificateValidationCallback)) {
try {
sslStreamRomoteClient.AuthenticateAsServer(serverCert, true, protocol, true);
byte[] buf = new byte[1000];
int len = sslStreamRomoteClient.Read(buf, 0, buf.Length);
string receive = Encoding.UTF8.GetString(buf, 0, len);
Console.WriteLine($"server receive:{receive}");
string send = "Hi, this message is from server";
sslStreamRomoteClient.Write(Encoding.UTF8.GetBytes(send));
Console.WriteLine($"server send:{send}");
} catch(Exception ex) {
Console.WriteLine("======Server Exception==========================");
Console.WriteLine(ex);
}
}
}
});
}
});
taskServer.Wait();
}
}
}
centos7 でopenssl-1.1.1h.tar.gzをコンパイルし、libssl.so.1.1 と libcrypto.so.1.1 を取得してから、これら 2 つのライブラリをプロジェクトに「コンテンツ」として追加しました。
今、このプログラムをcentosで実行しています(注:openssl1.1.1がインストールされていません)。このサーバーに接続しようとすると、次の例外が発生しました。
my assembly dir====>/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q
Server started
==============>New Connection from [::ffff:192.168.18.44]:58131
======Server Exception==========================
System.Security.Authentication.AuthenticationException: Authentication failed, s ee inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SS L_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:1408A0C1:SSL routines: ssl3_get_client_hello:no shared cipher
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, Byte[] recvBuf, Int3 2 recvOffset, Int32 recvCount, Byte[]& sendBuf, Int32& sendCount)
at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials cre dential, SafeDeleteContext& context, ArraySegment`1 inputBuffer, Byte[]& outputB uffer, SslAuthenticationOptions sslAuthenticationOptions)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken messa ge, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolTok en message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 cou nt, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readByte s, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtoco lRequest asyncRequest)
at System.Net.Security.SslStream.ForceAuthentication(Boolean receiveFirst, By te[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.ProcessAuthentication(LazyAsyncResult lazyRe sult, CancellationToken cancellationToken)
at System.Net.Security.SslStream.AuthenticateAsServer(SslServerAuthentication Options sslServerAuthenticationOptions)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverC ertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at TestTlsServer.Program.<>c__DisplayClass0_1.<Main>b__2()
これは、プログラムがこれらのライブラリをロードできないためだと思います
/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q/libcrypto.so.1.1
/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q/libssl.so.1.1
次に、このパスを LD_LIBRARY_PATH に追加します
export LD_LIBRARY_PATH=/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q:$LD_LIBRARY_PATH
今では正しく動作します!!
my assembly dir====>/var/tmp/.net/root/TestTlsServer/unsorm3j.o1q
Server started
==============>New Connection from [::ffff:192.168.18.44]:58172
server receive:Hi, this message is from client (C++)
server send:Hi, this message is from server
特別な理由により、ターゲットの Centos PC で openssl1.1.1 をインストールして LD_LIBRARY_PATH を変更するべきではありません。そのため、プログラムに libssl.so.1.1 と libcrypto.so.1.1 をパックしました。
プログラムは「LD_LIBRARY_PATH」を変更せずにライブラリを見つけるにはどうすればよいですか?
または
プログラムはどのようにして LD_LIBRARY_PATH を自分自身だけに変更できますか?
アドバイスをください!助けて!