如何解决为什么SSL无法在构建jar中工作?
作为主要示例,我使用了这个仓库:https://github.com/williamswhy/SSLSocket
这是我的服务器:
Server() {
SSLServerSocket serverSocket = null;
SSLSocket socket = null;
try {
SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
serverSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(3122);
MariaDB mariaDB = new MariaDB();
new Thread(mariaDB).start();
while (true) {
socket = (SSLSocket) serverSocket.accept();
new Thread(new ClientConnection(socket,mariaDB)).start();
}
} catch (IOException e) {
e.printstacktrace();
}
}
public static void main(String[] args) {
//System.setProperty("javax.net.debug","all");
System.setProperty("javax.net.ssl.keyStore","sslserverkeys");
System.setProperty("javax.net.ssl.keyStorePassword","password");
new Server();
}
我的客户使用以下类:
try {
System.setProperty("javax.net.ssl.trustStore","sslclienttrust");
System.setProperty("javax.net.ssl.trustStorePassword","password");
//DO NOT CHANGE THIS
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null,null,new SecureRandom());
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
socket = (SSLSocket) socketFactory.createSocket("localhost",3122);
System.out.println("Successfully initialized connection");
try {
this.out = new ObjectOutputStream(this.socket.getoutputStream());
System.out.println("Successfully opened ObjectOutputStream");
} catch (IOException var4) {
var4.printstacktrace();
try {
this.out.close();
} catch (IOException var3) {
var3.printstacktrace();
}
}
} catch (NoSuchAlgorithmException | KeyManagementException | IOException e) {
e.printstacktrace();
}
我在客户端的根文件夹中有一个sslclienttrust文件,在服务器的根文件夹中有sslserverkeys。我正在使用Maven在IntelliJ Ultimate中进行编码,并且该连接的工作方式就像它的魅力一样。 但是当我构建一个.jar(使用maven-shade-plugin)时,我得到了一个例外。
服务器引发以下异常:
javax.net.ssl.SSLException: readHandshakeRecord
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1392)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:441)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:889)
at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1251)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1893)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1802)
at java.base/java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:252)
at ClientConnection.<init>(ClientConnection.java:21)
at Server.<init>(Server.java:20)
at Server.main(Server.java:36)
Suppressed: java.net.socketException: An established connection was aborted by the software in your host machine
at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:420)
at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:826)
at java.base/java.net.socket$SocketoutputStream.write(Socket.java:1052)
at java.base/sun.security.ssl.SSLSocketoutputRecord.encodeAlert(SSLSocketoutputRecord.java:82)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:356)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:268)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:451)
... 8 more
Caused by: java.net.socketException: An established connection was aborted by the software in your host machine
at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:420)
at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:826)
at java.base/java.net.socket$SocketoutputStream.write(Socket.java:1052)
at java.base/sun.security.ssl.SSLSocketoutputRecord.flush(SSLSocketoutputRecord.java:268)
at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.onProduceFinished(Finished.java:783)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.produce(Finished.java:671)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:440)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1252)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1188)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:851)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:812)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:445)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:423)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1475)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1381)
... 9 more
客户端抛出以下内容:
the last modified time is: Mon Sep 28 00:44:21 CEST 2020
javax.net.ssl|DEBUG|15|Thread-4|2020-09-29 24:55:10.430 CEST|TrustStoreManager.java:334|Reload the trust store
javax.net.ssl|DEBUG|15|Thread-4|2020-09-29 24:55:10.468 CEST|TrustManagerFactoryImpl.java:70|SunX509: skip default keystore (
"throwable" : {
java.io.IOException: Keystore was tampered with,or password was incorrect
at java.base/sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:794)
at java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:241)
at java.base/java.security.KeyStore.load(KeyStore.java:1472)
at java.base/sun.security.ssl.TrustStoreManager$TrustAnchorManager.loadKeyStore(TrustStoreManager.java:390)
at java.base/sun.security.ssl.TrustStoreManager$TrustAnchorManager.getTrustedCerts(TrustStoreManager.java:336)
at java.base/sun.security.ssl.TrustStoreManager.getTrustedCerts(TrustStoreManager.java:56)
at java.base/sun.security.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java:49)
at java.base/javax.net.ssl.TrustManagerFactory.init(TrustManagerFactory.java:281)
at java.base/sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:94)
at java.base/javax.net.ssl.SSLContext.init(SSLContext.java:313)
at connection.ServerConnection.connectToServer(ServerConnection.java:204)
at connection.ServerConnection.run(ServerConnection.java:42)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.security.UnrecoverableKeyException: Password verification Failed
at java.base/sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:792)
... 12 more}
起初,我认为这与错误的路径有关,因此我尝试了sof中提到的几种方法。但是,密码错误或密钥库被篡改的错误使我感到困惑。密码不能错,因为它可以在IDE中使用。
为什么SSL可以在我的IDE中工作,但不能在.jar中工作 我看到一些关于SSL的线程根本不起作用,但不是这样。
解决方法
系统属性javax.net.ssl.trustStore
要求您传入文件,并且该文件必须存在。
罐子中的条目类似于文件,不是文件,因此您不能使用打包在罐子文件中的信任库文件。首先,这有点夸张了jar的观点,这就是为什么它不“起作用”的原因-您是从工作目录不正确的地方运行jar的。通常,将相对条目(不是以/
或C:\
开头的东西)传递给javax.net.ssl.trustStore
永远不会在最终用户的手中,因此需要仔细的脚本编写如果您尝试将其部署在自己的服务器上,则为ops团队。
要从任何随机源加载信任库,例如与类文件所在位置相同的“资源”文件;在jar文件中查找(如果需要),请选中this tutorial。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。