2

我在尝试连接到服务器的 SMTP 邮件服务器的服务器上有一个 java 方法,但出现此错误:

stack trace: org.apache.commons.mail.EmailException: Sending the email
to the following server failed : mail.mycompanyname.com:465

检索完整的堆栈跟踪后,我注意到以下行,它重复了 3 次/尝试:

 nested exception is:
 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

服务器在 Apache 服务器上安装了一个证书。但是,我使用 GlassFish 作为访问 java 方法的 Web 应用程序(在客户端)的应用程序服务器,而 GlassFish 位于 Apache Server 之后。我没有为这个证书调整 GlassFish 上的任何内容。

我看到其他一些类似的问题和答案,例如这里,但我不明白如何实现它:

PKIX 路径构建失败:无法找到请求目标的有效证书路径

另外,也有这个,但我不知道如何在我的情况下使用它,如果合适的话:

无法找到到所请求目标的有效证书路径 - 即使在导入证书后也会出错

所以我的问题是,从 Java 的角度来看,我需要做什么来清除这个错误?

我是否只需要创建一个属性文件,如此处所示?:

Java 应用程序的密钥库/信任库的默认位置是哪个?

或者,我是否还需要设置 TrustStore?

我需要在 GlassFish 上设置什么吗?

希望有人可以帮助我了解这里的基础知识。提前感谢您的任何评论。

更新:

好的,终于在下面 Hiro2K 的出色帮助下弄清楚了。所缺少的只是将 Apache Webserver 的 SMTP 邮件服务器使用的证书导入 GlassFish。Hiro2k 下面的命令运行良好,但我的麻烦是找到正确的证书。

使用WHM,我可以看到邮件服务器(在我的例子中是Exim)引用了host1.mycompany.com,所以我自然而然地选择了自签名的认证名称host1.mycompany.com.crt。但是,此证书已过期,因此无法使用。我必须进入 Exim 的配置文件以找到其名为 exim.crt 的证书,并将该证书导入 GlassFish。然后它起作用了。

另请注意,服务器上有许多证书,包括 imap(例如 imapd.pem)和 pop3(pop3.pem)等。非常混乱。

4

1 回答 1

3

所以 SMTP SSL 使用端口 465,这意味着客户端为了连接到服务器,必须信任服务器的证书。Java 和 Glassfish 有一个默认的信任库,它适用于由任何大型证书颁发机构(Thawt、Verisign 等)签署的任何证书,并且由于它不能正常工作,这让我相信你的服务器正在使用 self签署的 SSL 证书。

这不是问题,并且得到许多不想为这些证书付费的内部应用程序的完全支持。问题是 GlassFish 不知道该自签名证书,因此您必须将其导入默认 glassfish 信任库。您可以在 $GLASFISH_INSTALL_DIR$/domains/domain1/config/cacerts.jks 找到它

要导入证书,您可以使用 java.util.keytool 附带的 keytool。

keytool -importcert -v -noprompt -alias smtp.server.name -file 
/path/to/smtp.server.der -keystore
$GLASFISH_INSTALL_DIR$/domains/domain1/config/cacerts.jks -storepass changeit

您唯一需要注意的是证书的格式。Keytool 只支持二进制 DER 格式,很多 linux 服务器使用称为 PEM 的 OpenSSL 文本格式。使用 OpenSSL 很容易从一种转换到另一种。

openssl x509 -in input.crt -inform PEM –out output.der -outform DER
于 2013-06-26T16:43:38.643 回答