Клиент C #, подключающийся к серверу Java через SSL - PullRequest
2 голосов
/ 05 апреля 2009

В качестве командного проекта мне нужно подключиться от клиента C # к серверу SSL Java 6.5, однако, когда я попадаю в поток. Строка AuthenticateAsClient зависает.

код подключения C #

public static void connect(string server, Int32 port)
{
  try
  {
    client = new TcpClient(server, port);
    stream = new SslStream(client.GetStream(), false);
    stream.AuthenticateAsClient("MyCNfield");
...
...

Если я подключусь к чему-то вроде https://mail.google.com и установлю MyCNfield на mail.google.com, это будет нормально работать, поэтому я думаю, что это сторона Java.

Раздел Java Init:

public void initSSL() throws IOException, KeyStoreException, NoSuchAlgorithmException,
                             CertificateException, UnrecoverableKeyException, KeyManagementException {
    char[] passphrase = "scared".toCharArray();
    System.out.println(java.security.KeyStore.getDefaultType());
    boolean handshakedone=false;

    KeyStore keystore1 = KeyStore.getInstance("jks");
    FileInputStream fis = new FileInputStream("C:\\\\temp\\\\work.jks");
    keystore1.load(fis, passphrase);
    fis.close();
    KeyStore ksTrust = KeyStore.getInstance("jks");
    FileInputStream fis2 =  new FileInputStream("C:\\\\temp\\\\work.jks");
    ksTrust.load(fis2, passphrase);

    KeyManagerFactory kmf =    KeyManagerFactory.getInstance("SunX509");

    // KeyManager's decide which key material to use.
    kmf.init(keystore1, passphrase);

    // TrustManager's decide whether to allow connections.
    TrustManagerFactory tmf =   TrustManagerFactory.getInstance("SunX509");
    tmf.init(ksTrust);

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null);

    SSLServerSocketFactory sslserversocketfactory =(SSLServerSocketFactory) sslContext.getServerSocketFactory();
    sslserversocket =(SSLServerSocket) sslserversocketfactory.createServerSocket(2443);
    sslserversocket.setUseClientMode(false);

    //Context conte
    ServerSocketFactory serversocketfactory =(ServerSocketFactory) sslContext.getServerSocketFactory();

    //  serverSocket = new ServerSocket(2443);
    System.out.println("OK we are set up");
}

это называется:

sslsocket = (SSLSocket) sslserversocket.accept();

и продолжается, даже если соединение не было полностью аутентифицировано.

Что нужно изменить, чтобы это исправить: у JKS есть сертификат MyCNfield, подписанный созданным мной ЦС. Как мне импортировать цепочку сертификатов в мой частный CA в моем C # или как поменять самозаверяющие сертификаты с помощью Java и C # и просто выбросить мой текущий JKS?

1 Ответ

3 голосов
/ 15 марта 2012

Вам необходимо использовать механизм обратного вызова RemoteCertificateValidationCallback для обеспечения аутентификации сертификата. Вы не должны были закрывать вопрос, это правильный вопрос, который может возникнуть у многих людей. Этот ответ стал одним из первых попаданий в поиске в Google, благодаря великолепной оптимизации стекового потока, которая может привести людей по неверному пути.

Использование обратного вызова RemoteCertificateValidationCallback .

private readonly bool allowSsl;

// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(
object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors policyErrors
)
{
    if (allowSsl)
    {
        // allow any certificate...
        return true;
    }
    else
    {
        return policyErrors == SslPolicyErrors.None;
    }
}

А вот как вы могли бы использовать его с TCPClient :

TcpClient client = new TcpClient(machineName,443);
Console.WriteLine("Client connected.");

// Create an SSL stream, specifying the callback above.
SslStream sslStream = new SslStream(
    client.GetStream(), 
    false, 
    new RemoteCertificateValidationCallback (ValidateRemoteCertificate), 
    null
    );
...