6

SSL接続を受け入れるサーバーに証明書とパスワードを与えました。このサーバーに接続しようとしましたが、認証に失敗しました。これは主に、与えられたファイルとパスワードの使用方法がわからないためです。

これが私のコードです:

    X509Certificate certificate = new X509Certificate(
        @"c:\mySrvKeystore", KEY_PASSWORD);

    public static bool ValidateCertificate(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors errors)
    {
        if (errors == SslPolicyErrors.None)
            return true;

        Console.WriteLine("Certificate error: {0}", errors);
        return false;
    }

    public void RunClient(string address, int port)
    {
        Console.WriteLine("Starting client...");
        var client = new TcpClient(address, port);


        Console.WriteLine("Client connected.");


        var stream = new SslStream(client.GetStream(),false,
            ValidateCertificate, null);

        try
        {
            stream.AuthenticateAsClient(address);

            Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");

            //TODO constantly read from server!
        }
        catch (AuthenticationException ae)
        {
            Console.WriteLine("Exception occured: {0}", ae.Message);

            if (ae.InnerException != null)
            {
                Console.WriteLine("Inner exception: {0}", ae.InnerException.Message);
            }

            Console.WriteLine("Failed to authenticate! closing the client...");

            client.Close();

            return;
        }
        catch (Exception ex)
        {
            Console.WriteLine("General exception occured {0}", ex.Message);
            client.Close();
            return;
        }
    }

ご覧のとおり、私のコードには、このファイルとキーがあることをサーバー (TcpClient または SSLStream) に伝えるコードはありません!

問題なくサーバーに接続するJavaコードがありますが、まだC#に変換できませんでした。どんな助けでも素晴らしいでしょう!

    String keyPassword = "123456";
    // String keyPassword = "importkey";

    try {
        KeyManagerFactory keyManagerFactory;

        keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
        KeyStore keyStore = KeyStore.getInstance("JKS");
        InputStream keyInput = new FileInputStream("c:\\mySrvKeystore");
        keyStore.load(keyInput, keyPassword.toCharArray());
        keyInput.close();
        keyManagerFactory.init(keyStore, keyPassword.toCharArray());

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new java.security.SecureRandom());
        SSLSocketFactory sslsocketfactory = sc.getSocketFactory();
        this.sslsocket = (SSLSocket) sslsocketfactory.createSocket(host, port);

    } catch (java.security.NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (java.security.KeyManagementException e) {
        e.printStackTrace();
    } catch (java.security.KeyStoreException e) {
        e.printStackTrace();
    } catch (java.security.cert.CertificateException e) {
        e.printStackTrace();
    } catch (java.security.UnrecoverableKeyException e) {
        e.printStackTrace();
    } finally {}
}

public void run() {
    try {
        InputStream inputstream = sslsocket.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

        OutputStream outputstream = System.out;
        OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
        BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);

        //get text from server and stuff...no deal!

アップデート

gtrigに従ってキーを p12 に変換した後、問題は次のメソッドの IOExceptionAutheneticateAsClientです。

        try
        {
            var certificate = new X509Certificate2(@"d:\mySrvKeystore.p12", "123456");


            X509Certificate2[] X509Certificates = {certificate};
            var certsCollection = new X509CertificateCollection(X509Certificates);

            //IO EXCEPTION HERE-->
            stream.AuthenticateAsClient(address, certsCollection, SslProtocols.Ssl2, false);
            Console.WriteLine(stream.IsAuthenticated ? "Client authenticated." : "Client is not authenticated.");

            //TODO constantly read from server!
        }

またSSlProtocols.Default、エラーを使用すると、次のようになります。RemoteCertificateNameMismatch, RemoteCertificateChainErrors

4

2 に答える 2

5

この答えは、あなたをそこまで導くものではないかもしれませんが、あなたを近づけるはずです。

秘密鍵と対応する証明書を含む Java KeyStore (JKS) が提供されました。コードによるとJKSを開くためのパスワードは「123456」です。

JKS には秘密鍵が含まれているため、Java コードを見ると、双方向 (相互) SSL 接続が必要であると思われます。これは基本的に、クライアントがサーバーを認証し、サーバーがあなたを認証することを意味します。この JKS ファイルは、サーバーを使用するための資格情報です。

では、これを C# でどのように使用しますか? まず、次のコマンドで JKS を PKCS12 キーストアに変換しましょう。

keytool -importkeystore -srckeystore mySrvKeystore -destkeystore mySrvKeystore.p12 -srcstoretype JKS -deststoretype PKCS12

これで、PKCS12 ファイルを Windows キーストアにインポートできるようになりました。これにより、C# から簡単にアクセスできるようになります。または、次のコードを使用してX509Certificate2オブジェクトにインポートできます。

X509Certificate2 cert = X509Certificate2("C:\Path\mySrvKeystore.p12", "123456");

これで、Windows キーストアまたは C# の X509Certificate2 オブジェクトを使用して、SSL 接続を確立できます。

于 2013-11-10T22:12:08.767 に答える