修复 错误 Javax.Net.SSL.SSLHandshakeException
本篇文章介绍了 Java 中的 javax.net.ssl.SSLHandshakeException
错误。
Java 中的 SSL 握手
SSL 握手用于客户端和服务器建立安全连接所需的信任和后勤保障。 SSL 握手操作需要遵循以下典型步骤:
- 首先,客户端将提供所有可能的密码套件和 SSL 版本的列表。
- 然后,服务器将就特定的密码套件和 SSL 版本达成一致,并以证书进行响应。
- 然后,客户端将从给定证书中提取公钥并使用新的加密预主密钥进行响应。
- 然后,服务器将使用私钥来解密预主密钥。
- 然后,客户端和服务器将使用预主密钥一起计算共享密钥。
- 最后,客户端和服务器将交换消息,确认共享密钥的加密和解密成功。
SSL 握手有两种类型。 第一种是单向 SSL,它让服务器信任所有客户端;第二种是双向 SSL,其中客户端和服务器必须接受彼此的证书。
了解了 SSL 握手之后,我们现在可以详细讨论 SSLHandShakeException。 SSLHandShakeException有两种情况,如下所示。
修复由于缺少服务器证书而导致的 SSLHandshakeException
如果客户端连接服务器时的 SSL 握手操作没有收到任何证书,则会抛出 SSLHandShakeException,如下所示:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
Received fatal alert: handshake_failure
要解决此问题,请确保遵循上述所有步骤。 当密钥库或系统属性输入不正确时,会出现此问题。
Keystore是权威机构提供的证书,或者我们也可以使用JDK的keytool功能来创建我们的Keystore。 以下是密钥库的示例:
$ keytool -genkey -keypass password \
-storepass password \
-keystore Server_Keystore.jks
上面的keytool代码是写在Keystore文件中的。 现在可以使用 keytool 从上面生成的密钥库文件中提取公共证书:
$ keytool -export -storepass password \
-file NewServer.cer \
-keystore Server_Keystore.jks
上面的代码将从密钥库中将公共证书导出为文件 NewServer.cer。 现在,我们可以将其添加到客户端的信任库中:
$ keytool -import -v -trustcacerts \
-file NewServer.cer \
-keypass password \
-storepass password \
-keystore Client_Truststore.jks
现在服务器的密钥库和客户端的信任库已生成。 我们可以使用命令将它们作为系统属性传递给服务器:
-Djavax.net.ssl.keyStore=Client_Keystore.jks -Djavax.net.ssl.keyStorePassword=password
这是系统属性所必需的。 密钥库文件路径必须是绝对路径,或者将密钥库文件放置在调用命令的同一目录中。
不支持相对路径。 一旦遵循此过程,丢失证书错误将得到解决,并且不会再出现 SSLHandShakeException。
修复由于不受信任的服务器证书导致的 SSLHandShakeException
SSLHandShakeException 的另一个原因是服务器证书不受信任。 当服务器使用未经权威机构签名的自签名证书时,它将抛出以下错误:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
每当证书由默认存储之外的任何实体签名时,都会引发此异常。 JDK 中的默认信任库提供有关正在使用的常见证书的信息。
这个问题可以通过强制客户端信任服务器提供的证书来解决。 我们需要使用上面生成的信任库并将它们作为系统属性传递给客户端:
-Djavax.net.ssl.trustStore=Client_Truststore.jks -Djavax.net.ssl.trustStorePassword=password
这将解决异常,但这不是理想的情况。 在理想情况下,我们可以使用自签名证书,该证书应该由证书颁发机构(CA)认证,然后客户端可以默认信任它们。
修复因证书错误导致的 SSLHandShakeException
由于证书不正确,握手也可能失败。 当证书未正确创建时,会抛出 SSLHandShakeException:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:
No name matching localhost found
要检查证书是否已正确创建,请运行以下命令:
keytool -v -list -keystore Server_Keystore.jks
上面的命令将显示密钥库所有者的详细信息:
...
Owner: CN=localhost, OU=technology, O=delftstack, L=city, ST=state, C=xx
..
所有者的 CN 必须与服务器的 CN 匹配,如果不匹配,则会抛出与上面所示的相同的异常,因为它是由于 CN 不同而生成的。
修复 SSL 版本和密码套件不兼容导致的 SSLHandShakeException
在 SSL 握手操作时,可能会存在各种加密协议,例如不同版本的 SSL、TLS 等。虽然客户端和服务器必须在握手时就加密协议和版本达成一致,但 SSL 会被 TLS 取代 它的加密强度。
现在,例如,如果服务器使用协议 SSL3,而客户端使用协议 TLS1.3,则双方无法就加密协议达成一致,并且会抛出 SSLHandShakeException:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
为了解决这个问题,我们必须验证客户端和服务器是否使用相同或兼容的加密协议。
同样,也需要有兼容的密码套件。 握手时,客户端提供密码列表,服务器将选择要使用的密码。
如果服务器无法选择合适的密码,代码将抛出以下 SSLHandShakeException:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
Received fatal alert: handshake_failure
通常客户端和服务器端使用多种密码套件; 这就是发生此错误的原因。 发生该错误的原因是服务器选择了选择性很强的密码。
为了避免这个问题,服务器使用选择性密码列表,这也有利于安全。
相关文章
解决 Java.Lang.RuntimeException: Unable to Instantiate Activity ComponentInfo
发布时间:2023/07/12 浏览次数:191 分类:Java
-
我们将探讨导致 java.lang.RuntimeException: Unable to instantiate Activity ComponentInfo 的不同可能原因。 最后,我们将有一个解决方案来根除它。解决 java.lang.RuntimeException: Unable to instantiate Activity ComponentIn
解决 Java 中 Generic Array Creation 错误
发布时间:2023/07/12 浏览次数:189 分类:Java
-
本篇文章通过代码示例说明了 generic array creation 错误,并重点介绍了创建通用数组时出现此错误的原因。 本次讨论将得出解决方案,我们将学习如何使用对象数组和反射功能创建通用数组。
Java.Net.UnknownHostException 异常
发布时间:2023/07/12 浏览次数:190 分类:Java
-
本篇文章介绍了 Java 中的 java.net.UnknownHostException 错误。Java中java.net.UnknownHostException的原因 java.net.UnknownHostException 表示找不到主机名的 IP 地址。
Java 中异常 java.lang.ClassCastException
发布时间:2023/07/12 浏览次数:72 分类:Java
-
当我们尝试将对象从父类转换为子类的对象时,会引发 java.lang.ClassCastException。 但是,如果我们尝试在两个完全不相关的类型之间转换对象,也可能会抛出该错误。本文将帮助您处理 Java 的 j
Java StackOverflowError 错误
发布时间:2023/07/12 浏览次数:190 分类:Java
-
本文解决了 Java 程序的 main() 方法中出现 java.lang.StackOverflowError 错误的可能原因。Java 中的 java.lang.StackOverflowError Java 中抛出 java.lang.StackOverflowError 表示应用程序的堆栈由于特别深的递归而已耗尽
修复 Java Unexpected Type 错误
发布时间:2023/07/12 浏览次数:132 分类:Java
-
本篇文章介绍了 Java 中的 Unexpected Type 错误。修复Java unexpected type 错误 当我们尝试将值分配给值或表达式而不是变量时,就会发生 Java 意外类型错误。
修复 Class X Is Public Should BeDeclared in a File Named X.java 错误
发布时间:2023/07/12 浏览次数:192 分类:Java
-
我们将经历各个阶段,从演示一个编译时错误开始,该错误指出类 X 是公共的,应该在名为 X.java 的文件中声明。 class X is public, should be declared in a file named X.java 的原因 然后,我们将看到导致此
Java 错误 Could Not Reserve Enough Space for Object Heap Minecraft
发布时间:2023/07/11 浏览次数:125 分类:Java
-
本篇文章介绍了 Java 中的 Could not reserve enough space for object heap 错误。Minecraft 是一款非常流行的用 Java 开发的游戏,我们需要 Java 来运行它。Java 中Minecraft 错误Could not reserve enough space for object h
Java 错误 Cannot Determine a Valid Java Home
发布时间:2023/07/11 浏览次数:149 分类:Java
-
本篇文章介绍了 Java 中的 cannot determine a valid java home 错误。当 Java Home 路径设置不正确时,会出现 cannot determine a valid java home 错误。 我们必须按照以下步骤正确设置我们的 Java Home 来解决这个问