2009-04-05 7 views
2

En tant que projet d'équipe, je dois me connecter à partir d'un client C# vers un serveur SSL Java 6.5, mais lorsque j'arrive à la ligne stream.AuthenticateAsClient, il se bloque.Client C# se connectant à un serveur Java via SSL

C# connecter Code

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

Si je me connecte à quelque chose comme https://mail.google.com et mis MyCNfield à mail.google.com, il fonctionne très bien, donc je pense qu'il est du côté Java.

La section Java Init est:

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"); 
} 

il est appelé:

sslsocket = (SSLSocket) sslserversocket.accept(); 

et se poursuit, même si la connexion n'a pas été entièrement authentifié.

Ce qui doit être modifié pour résoudre ce problème: le JKS a un certificat MyCNfield qui est signé par une autorité de certification que j'ai créée. Comment est-ce que j'importe la chaîne de cert à mon CA privé dans mon C#, ou comment j'échange des certs auto-signés avec Java et C#, et jette juste mon JKS courant?

Répondre

3

Vous devez utiliser le mécanisme de rappel RemoteCertificateValidationCallback pour fournir l'authentification par certificat. Vous ne devriez pas avoir fermé la question, c'est une question valable que beaucoup de gens peuvent avoir. Cette réponse a été l'un des premiers résultats d'une recherche sur google, grâce au bon référencement de stackoverflow, ce qui peut conduire les gens sur le mauvais chemin. Rappel

Utilisez le rappel 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; 
    } 
} 

Et voici comment vous l'utiliser avec 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 
    ); 
+0

Je ne sais pas si cela va fonctionner et je ne peux pas tester comme ce projet est révolue depuis longtemps, mais Je vais vous donner la réponse acceptée car vous semblez savoir de quoi vous parlez. –

+0

Cela fonctionne, je viens de faire un POC. La seule mise en garde est que vous devez vous assurer que votre clé privée est dans le magasin de la machine locale. Ceci est différent de java qui vous permet de spécifier n'importe quel emplacement en tant que keystore. Assurez-vous simplement d'installer vos certificats dans le magasin de machines local. – SRM

Questions connexes