2009-04-05 7 views
2

팀 프로젝트로서 C# 클라이언트에서 Java 6.5 SSL 서버로 연결해야하지만 stream.AuthenticateAsClient 행에 도달하면 중단됩니다. 내가 https://mail.google.com 같은에 연결하고 mail.google.comMyCNfield을 설정하면SSL을 통해 Java 서버에 연결하는 C# 클라이언트

C 번호는 잘 작동 코드를

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

을 연결하는, 그래서 그것을 자바 측라고 생각합니다. 연결이 완전히 인증되지에도 불구하고,

sslsocket = (SSLSocket) sslserversocket.accept(); 

과에 계속 :

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

은이 호출됩니다 :

자바 초기화 부분이다.

이 문제를 해결하려면 무엇을 변경해야합니까? JKS에는 작성한 CA에서 서명 한 인증서 MyCNfield이 있습니다. 내 C#에서 내 사설 CA에 인증서 체인을 가져 오거나 어떻게 자체 서명 된 인증서를 Java 및 C#으로 전환하고 현재 JKS를 폐기합니까?

답변

3

인증서 인증을 제공하려면 RemoteCertificateValidationCallback 콜백 메커니즘을 사용해야합니다. 당신은 질문을 마감해서는 안된다. 이것은 많은 사람들이 가질 수있는 유효한 질문이다. 이 답변은 stackoverflow의 훌륭한 SEO 덕분에 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 
    ); 
+0

하지만, 나는 당신이 말하는 것에 대해 알고있는 것처럼 받아 들여진 대답을 줄 것이다. –

+0

작동합니다, 방금 POC를했습니다. 유일한주의 사항은 개인 키가 로컬 컴퓨터 저장소에 있는지 확인해야한다는 것입니다. 이것은, java와는 다른 것으로, 임의의 장소를 키 스토어로서 지정할 수 있습니다. 로컬 컴퓨터 저장소에 인증서를 설치했는지 확인하십시오. – SRM