我想用java启动apachehttp服务器。
过了一会儿,我找到了这个答案。按照上面的指示做了。
这个 KeyStore
是根据这个指令创建的。
我的代码现在:
import me.project.Main;
import org.apache.http.ExceptionLogger;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.bootstrap.HttpServer;
import org.apache.http.impl.bootstrap.ServerBootstrap;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
public class Server {
private static final Logger logger = LoggerFactory.getLogger(Server.class);
private static HttpServer server;
public static void createAndStart() {
if (server != null) return;
SSLContext sslContext = prepareSSLContext();
SocketConfig config = SocketConfig.custom().setSoTimeout(1500).setTcpNoDelay(true).build();
server = ServerBootstrap.bootstrap()
.setListenerPort(43286)
.setServerInfo("Test")
.setSocketConfig(config)
.setSslContext(sslContext)
.setExceptionLogger(ExceptionLogger.STD_ERR)
.registerHandler("/", new HelloPage())
.create();
System.out.println("Ok");
try {
server.start();
} catch (IOException ioException) {
logger.error("Cannot start server: ", ioException);
}
}
private static SSLContext prepareSSLContext() {
URL keyStoreFile = Main.class.getClassLoader().getResource("keystore.jks");
if (keyStoreFile == null) {
logger.error("Key store not found");
System.exit(1);
}
SSLContext sslContext = null;
try {
sslContext = SSLContexts.custom()
.loadKeyMaterial(keyStoreFile, "mysuperpass".toCharArray(), "mysuperpass".toCharArray()).build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException | CertificateException | IOException e) {
logger.error("Cannot init ssl context", e);
}
return sslContext;
}
}
它成功启动并打印“ok”。
但有几件事我还是不明白:
在我看来,这仍然是ssl协议,而不是tls
如何确保服务器真正使用加密的tls协议进行通信(除了拦截流量和监视)
你觉得 loadKeyMaterial (keyStore, storePass, KeyPass)
方法知道在没有密钥别名的情况下从存储中获取哪个密钥?
我在这里找到了另一个启用tls的例子,但是我不知道在哪里使用这个对象 conn
之后:
DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1204);
conn.bind(socket);
对不起,我不懂英语,用谷歌翻译了这个
1条答案
按热度按时间sdnqo3pr1#
在我看来,这仍然是ssl协议,而不是tls
这些类最初是在20世纪90年代为ssl(v3)实现的,但它们从2000年开始就实现了tls(最初是1.0,后来是1.1.2,现在是1.3),而为了兼容性,它们的名称保持不变。事实上,自2014年8u31以来,sslv3在jvm配置中被默认禁用,因为它被“poodle”攻击破坏,“ssl”类实际上只提供tls。
如何确保服务器真正使用加密的tls协议进行通信(除了拦截流量和监视)
尝试使用tls和非tls工具连接到它。
你觉得
loadKeyMaterial (keyStore, storePass, KeyPass)
方法知道在没有密钥别名的情况下从存储中获取哪个密钥?它使用jsse默认值
KeyManager
哪个实现了chooseServerAlias
返回第一个密钥和证书条目(即。PrivateKeyEntry
)它发现这适用于支持客户端的ciphersuite——或者对于tls 1.3,如果它不再在ciphersuite中,则适用于支持客户端的sigalg。iirc“first”是按hashmap定义的顺序,这意味着出于实际/人类目的,它是任意的。但是大多数服务器使用的密钥库只包含一个privatekeyentry,所以所有的选择序列都是相同的。