0

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 つのライブラリをプロジェクトに「コンテンツ」として追加しました。 ここに画像の説明を入力

このプロジェクトを 1 つのファイルに発行する
ここに画像の説明を入力

今、このプログラムを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 を自分自身だけに変更できますか?

アドバイスをください!助けて!

4

0 に答える 0