13

Java サーバー アプリケーションでセキュアなリッスン ソケットを開きたいと考えています。これを行うための推奨される方法は、これを行うことです。

SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket ss = ssf.createServerSocket(443);

ただし、これには、Java の起動時にサーバーの証明書を JVM に渡す必要があります。これにより展開が複雑になるため、実行時に証明書をロードすることをお勧めします。

キーファイルとパスワードがあり、サーバーソケットが必要です。どうやってそこまで行くの?さて、私はドキュメントを読みましたが、私が見つけることができる唯一の方法はこれです:

// these are my parameters for SSL encryption
char[] keyPassword =  "P@ssw0rd!".toCharArray();
FileInputStream keyFile = new FileInputStream("ssl.key"); 

// init keystore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keyFile, keyPassword);
// init KeyManagerFactory
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyPassword);
// init KeyManager
KeyManager keyManagers[] = keyManagerFactory.getKeyManagers();
// init the SSL context
SSLContext sslContext = SSLContext.getDefault();
sslContext.init(keyManagers, null, new SecureRandom());
// get the socket factory
SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();

// and finally, get the socket
ServerSocket serverSocket = socketFactory.createServerSocket(443);

そして、それにはエラー処理さえありません。本当にそんなに複雑ですか?もっと簡単にできる方法はありませんか?

4

3 に答える 3

8

ただし、これには、Java の起動時にサーバーの証明書を JVM に渡す必要があります。

いいえ、そうではありません。を作成する前に、これらのシステム プロパティを設定するだけです。SSLServerSocket:

javax.net.ssl.keyStore ssl.key
javax.net.ssl.keyStorePassword P@ssw0rd!

System.setProperties() コマンドラインまたはコマンドラインでそれを行うことができます。

于 2012-09-11T23:31:57.047 に答える
2

コードを見れば、それが必然的に複雑である理由がわかります。このコードは、SSL プロトコルの実装を次のものから分離します。

  • 鍵素材のソース ( KeyStore)
  • 証明書アルゴリズムの選択とキー管理 ( KeyManager)
  • ピア信頼ルールの管理 ( TrustManager) - ここでは使用しません
  • 安全なランダム アルゴリズム ( SecureRandom)
  • NIO またはソケットの実装 ( SSLServerSocketFactory) - SSLEngineNIO に使用できます

同じ目標を達成しようとしている場合、独自の実装がどのようになるかを検討してください!

于 2012-09-11T14:15:14.377 に答える
1

これを使って。

public class KeyMaster
{
     public static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String sslAlgorithm)
{
    try
    {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustKey);

        SSLContext context = SSLContext.getInstance(sslAlgorithm);//"SSL" "TLS"
        context.init(null, tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    catch(Exception e)
    {
        Assistance.log("Err: getSSLSocketFactory(), ");
    }

    return null;
}

public static SSLServerSocketFactory getSSLServerSocketFactory(KeyStore trustKey, String sslAlgorithm)
{
    try
    {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustKey);

        SSLContext context = SSLContext.getInstance(sslAlgorithm);//"SSL" "TLS"
        context.init(null, tmf.getTrustManagers(), null);

        return context.getServerSocketFactory();
    }
    catch(Exception e)
    {
        Assistance.log("Err: getSSLSocketFactory(), ");
    }

    return null;
}

public static SSLServerSocket getSSLServerSocket(SSLServerSocketFactory socketFactory, int port)
{
    try
    {
        return (SSLServerSocket) socketFactory.createServerSocket(port);
    }
    catch(Exception e)
    {Assistance.log("Err: getSSLSocket(), ");}

    return null;
}

public static KeyStore getFromPath(String path, String algorithm, String filePassword)//PKSC12
{
    try
    {
        File f = new File(path);

        if(!f.exists())
            throw new RuntimeException("Err: File not found.");

        FileInputStream keyFile = new FileInputStream(f);
        KeyStore keystore = KeyStore.getInstance(algorithm);
        keystore.load(keyFile, filePassword.toCharArray());
        keyFile.close();

        return keystore;
    }
    catch(Exception e)
    {
        Assistance.log("Err: getFromPath(), " + e.toString());
    }

    return null;
}

そしてメインに。

 KeyStore key = KeyMaster.getFromPath(".\\cssl.pfx", "PKCS12", "123");
        SSLServerSocketFactory fac = KeyMaster.getSSLServerSocketFactory(key, "TLS");
        listener = KeyMaster.getSSLServerSocket(fac, 49015);
于 2018-06-17T14:20:34.650 に答える