2013-10-04 7 views
1

처음에 비슷한 질문이 있음을 알고 있습니다.하지만 의심의 여지가 없습니다. SSL로 구성된 FTPS 서버 (vsftpd)가 있습니다.apache-commons net에서 생성 된 인증서를 사용하여 클라이언트 인증을 구성하는 방법

나는 함께 해당 키 생성했습니다

openssl req -x509 -nodes -days 1825 -newkey rsa:2048 \ 
-keyout private/vsftpd.key \ 
-out certs/vsftpd.crt 

를 그리고 서버의 각 conf의 파일을 구성. ,

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.PrintWriter; 
import org.apache.commons.net.PrintCommandListener; 
import org.apache.commons.net.ftp.FTP; 
import org.apache.commons.net.ftp.FTPReply; 
import org.apache.commons.net.ftp.FTPSClient; 

public class CommonsNetFTPSTest { 
public static void main(String[] args) throws Exception { 
    System.setProperty("javax.net.debug", "ssl"); 

    String server = "XXX.XXX.XXX.XXX"; 
    String username = "USER_TEST"; 
    String password = "ABCD1234"; 
    String remoteFile = "/Data/Input/PH240819"; 
    String localFile = "PH240819"; 
    String protocol = "SSL"; // TLS/null (SSL) 
    int port = 990; 
    int timeoutInMillis = 10000; 
    boolean isImpicit = true; 

    FTPSClient client = new FTPSClient(protocol, isImpicit); 

    client.setDataTimeout(timeoutInMillis); 
    client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); 

    System.out.println("################ Connecting to Server ################################"); 

    try 
    { 
     int reply; 
     System.out.println("################ Connect Call ################################"); 
     client.connect(server, port); 

     client.login(username, password); 

     System.out.println("################ Login Success ################################"); 

     //client.setFileType(FTP.BINARY_FILE_TYPE); 
     client.setFileType(FTP.NON_PRINT_TEXT_FORMAT); 
     client.execPBSZ(0); // Set protection buffer size 
     client.execPROT("P"); // Set data channel protection to private 
     client.enterLocalPassiveMode(); 

     System.out.println("Connected to " + server + "."); 
     reply = client.getReplyCode(); 

     if (!FTPReply.isPositiveCompletion(reply)) 
     { 
      client.disconnect(); 
      System.err.println("FTP server refused connection."); 
      System.exit(1); 
     } 

     client.listFiles(); 
     boolean retrieved = client.retrieveFile(remoteFile, new FileOutputStream(localFile)); 
    } 
    catch (Exception e) 
    { 
     if (client.isConnected()) 
     { 
      try 
      { 
       client.disconnect(); 
      } 
      catch (IOException ex) 
      { 
       ex.printStackTrace(); 
      } 
     } 
     System.err.println("Could not connect to server."); 
     e.printStackTrace(); 
     return; 
    } 
    finally 
    { 
     //client.disconnect(); 
     client.logout(); 
     System.out.println("# client disconnected"); 
    } 
} 
} 

하지만 내 클라이언트는 모든 인증서를 받고있다 그런 식으로 :

지금, 아파치 평민의 그물 자바 클라이언트 코드에서,이 같은 뭔가 SSL을 통해 서버와 통신 할 수 있어요 중간자 공격이 가능할 수도 있습니다. 그래서 내 고객에게 어떤 인증서를 수락할지 알려주고 인증서가 유효 할 때만 연결합니다. vsftpd.key 및 vsftpd.crt을, 나는 다음과 같은 로컬 키 스토어에서 CRT 파일을 가져온 :

는 지금, 나는이 두 파일은 이전에 생성 한

내 질문은
keytool -import -alias alias -file vsftps.crt -keypass keypass -keystore mykeystore.jks -storepass Hello1 

, 어떻게 할 내 고객에게 mykeystore의 인증서를 사용하도록 알려주십시오. 내가 뭘 놓치고 있니?. 감사합니다

답변

3

좋아, 이제 알겠습니다.

처음부터 잘못하고있었습니다. 먼저 두 파일 (vsftpd.crt 및 vsftpd.key)을 PKCS12 파일로 변환해야합니다.

openssl pkcs12 -export -in vsftpd.crt -inkey vsftpd.key > vsftpd.p12 

다음, 당신은 키 저장소에 PKCS12 파일을 가져와야 :

keytool -importkeystore -srckeystore vsftpd.p12 -destkeystore keystore.jks -srcstoretype pkcs12 

자세한 설명은 [여기]를. 2

마지막으로 생성 된 키 저장소로 트러스트 관리자를 인스턴스화하고이를 FTPSClient에 전달하면됩니다. 다음과 같음 :

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import javax.net.ssl.X509TrustManager; 

import org.apache.commons.net.ftp.FTP; 
import org.apache.commons.net.ftp.FTPSClient; 
import org.apache.commons.net.io.Util; 
import org.apache.commons.net.util.TrustManagerUtils; 

public method() throws IOException, GeneralSecurityException{ 

    File storeFile = new File("path/to/keystore"); 

    KeyStore keyStore = loadStore("JKS", storeFile, "password"); 
    X509TrustManager defaultTrustManager = TrustManagerUtils.getDefaultTrustManager(keyStore); 

    client = new FTPSClient(properties.getProtocol(), isImpicit); 

    client.setTrustManager(defaultTrustManager); 
    logOutput = new LogOutputStream(log, Level.INFO); 
} 

//Helper method from apache: http://commons.apache.org/proper/commons-net/apidocs/index.html?org/apache/commons/net/util/KeyManagerUtils.html 
private KeyStore loadStore(String storeType, File storePath, String storePass) 
     throws KeyStoreException, IOException, GeneralSecurityException { 
     KeyStore ks = KeyStore.getInstance(storeType); 
     FileInputStream stream = null; 
     try { 
      stream = new FileInputStream(storePath); 
      ks.load(stream, storePass.toCharArray()); 
     } finally { 
      Util.closeQuietly(stream); 
     } 
     return ks; 
    }