【问题标题】:JavaMail (TLS): Erratic failure to validate certification pathJavaMail (TLS):验证证书路径异常失败
【发布时间】:2016-06-12 19:42:46
【问题描述】:

当尝试使用 JavaMail 库验证 TLS 连接时,我随机收到以下验证错误:

javax.mail.MessagingException: Can't send command to SMTP host;
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

我在 Linux 机器上运行,使用 jdk1.7.0 并使用最新的 jdk 的 cacerts 文件(撰写本文时为 1.8.0_73),我对此已导入 smtp 服务器证书。

smtp 服务器是一个 exchange 服务器,带有明文 TLS 验证。

我说随机是因为有时连接成功,但有时它抱怨无法识别证书验证路径并失败,似乎没有给定的模式。

一般重试连接都可以,虽然重试次数不一致,有时不需要,有时2或3次,有时超过20次。

为了消除任何外部影响,我编写了一个简单的邮件发送应用程序,我用它来调查这个问题(我们的应用程序在 Tomcat 部署上运行),所以我可以确定问题出在其中一个:

  • JDK
  • JavaMail 库
  • 网络连接

我的问题是,是否有人知道这种行为背后可能存在的任何限制/错误/问题?

目前重试连接已足够解决问题,但我们的项目需要将其作为永久解决方案不受欢迎,因为许多消息是异步发送的,并且在连接失败的情况下,用户将不会收到失败的反馈。


编辑:更多信息

服务器证书是通过openssl获取的,即这个命令:

openssl s_client -connect exchange.***.com:25 -starttls smtp 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > certificate.pem

请注意,如果没有 starttls 参数,该命令将不起作用(需要一段时间才能弄清楚,因为大多数在线资源,包括此处的 SO,都不会包含该步骤)。 原始 openssl 命令的(清理后的)输出如下:

depth=0 CN = smtpserver-ch-01
verify error:num=20:unable to get local issuer certificate

verify return:1
depth=0 CN = smtpserver-ch-01
verify error:num=21:unable to verify the first certificate
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:/CN=smtpserver-ch-01
   i:/CN=smtpserver-ch-01
---
Server certificate
-----BEGIN CERTIFICATE-----
  *** CERTIFICATE DATA
-----END CERTIFICATE-----
subject=/CN=smtpserver-ch-01
issuer=/CN=smtpserver-ch-01
---
No client certificate CA names sent
---
SSL handshake has read *** bytes and written *** bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: ***
    Session-ID-ctx: 
    Master-Key: ***
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: ***
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
250 XSHADOW

以下是 javax.net.debug=ssl 输出的 ma​​ssive 打印: (希望发布这些大量的文本转储是一种好的形式)

Sending message to test@server.com; Attempt attempt 0 of 20...
keyStore is : 
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trustStore is: certs/cacerts_1.8.0_73
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:

   ** Standard certificates **

adding as trusted cert:
  Subject: CN=smtpserver-ch-01
  Issuer:  CN=smtpserver-ch-01
  Algorithm: RSA; Serial number: **********************************
  Valid from ddd MMM DD 00:00:00 CEST 2013 until ddd MMM DD 00:00:00 CEST 2018

adding as trusted cert:

   ** The rest of the standard certificates **

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: XXX bytes = { XXX, ··· XXX }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension server_name, server_name: [host_name: exchange.***.com]
***
main, WRITE: TLSv1 Handshake, length = **
main, READ: TLSv1 Handshake, length = ***
*** ServerHello, TLSv1
RandomCookie:  GMT: XXX bytes = { XXX, ··· XXX }
Session ID:  {XX, ··· XXX}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=smtpserver-ch-02
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, xxx bits
  modulus: ***
  public exponent: ***
  Validity: [From: ddd MMM DD 00:00:00 CEST 2013,
               To: ddd MMM DD 00:00:00 CEST 2018]
  Issuer: CN=smtpserver-ch-02
  SerialNumber: [    xxx ]

Certificate Extensions: 4
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[4]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: smtpserver-ch-02
  DNSName: smtpserver-ch-02.domain.com
]

]
  Algorithm: [SHA1withRSA]
  Signature:

  *** SIGNATURE HEX DUMP ***

]
***
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: 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
Failed attempt: javax.mail.MessagingException: Can't send command to SMTP host


Sending message to test@server.com; Attempt attempt 1 of 20...
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: XXX bytes = { XXX, ··· XXX }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension server_name, server_name: [host_name: exchange.***.com]
***
main, WRITE: TLSv1 Handshake, length = **
main, READ: TLSv1 Handshake, length = **
*** ServerHello, TLSv1
RandomCookie:  GMT: XXX bytes = { XXX, ··· XXX }
Session ID:  {XXX, ··· XXX}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized:  [Session-2, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=smtpserver-ch-02
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 2048 bits
  modulus: ***
  public exponent: ***
  Validity: [From: ddd MMM DD 00:00:00 CEST 2013,
               To: ddd MMM DD 00:00:00 CEST 2018]
  Issuer: CN=smtpserver-ch-02
  SerialNumber: [    xxx]

Certificate Extensions: 4
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[4]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: smtpserver-ch-02
  DNSName: smtpserver-ch-02.domain.com
]

]
  Algorithm: [SHA1withRSA]
  Signature:

  *** SIGNATURE HEX DUMP ***
]
***
%% Invalidated:  [Session-2, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: 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
Failed attempt: javax.mail.MessagingException: Can't send command to SMTP host


Sending message to test@server.com; Attempt attempt 2 of 20...
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_RC4_128_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_RC4_128_SHA
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: XXX bytes = { XXX, ··· XXX }
Session ID:  {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension server_name, server_name: [host_name: exchange.***.com]
***
main, WRITE: TLSv1 Handshake, length = **
main, READ: TLSv1 Handshake, length = **
*** ServerHello, TLSv1
RandomCookie:  GMT: *** bytes = { XXX, ··· XXX }
Session ID:  {XXX, ··· XXX}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized:  [Session-3, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: CN=smtpserver-ch-01
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 2048 bits
  modulus: ***
  public exponent: ***
  Validity: [From: ddd MMM DD 00:00:00 CEST 2013,
               To: ddd MMM DD 00:00:00 CEST 2018]
  Issuer: CN=smtpserver-ch-01
  SerialNumber: [    XXX]

Certificate Extensions: 4
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[4]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: smtpserver-ch-01
  DNSName: smtpserver-ch-01.domain.com
]

]
  Algorithm: [SHA1withRSA]
  Signature:

  *** SIGNATURE HEX DUMP ***

]
***
Found trusted certificate:
[
[
  Version: V3
  Subject: CN=smtpserver-ch-01
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 2048 bits
  modulus: ***
  public exponent: ***
  Validity: [From: ddd MMM DD 00:00:00 CEST 2013,
               To: ddd MMM DD 00:00:00 CEST 2018]
  Issuer: CN=smtpserver-ch-01
  SerialNumber: [    XXX]

Certificate Extensions: 4
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:false
  PathLen: undefined
]

[2]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  serverAuth
]

[3]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

[4]: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: smtpserver-ch-01
  DNSName: smtpserver-ch-01.domain.com
]

]
  Algorithm: [SHA1withRSA]
  Signature:

    *** SIGNATURE HEX DUMP ***

]
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
main, WRITE: TLSv1 Handshake, length = ***
SESSION KEYGEN:
PreMaster Secret:
  *** HEX DUMP
CONNECTION KEYGEN:
Client Nonce:
  *** HEX DUMP
Server Nonce:
  *** HEX DUMP
Master Secret:
  *** HEX DUMP
Client MAC write Secret:
  *** HEX DUMP
Server MAC write Secret:
  *** HEX DUMP
Client write key:
  *** HEX DUMP
Server write key:
  *** HEX DUMP
Client write IV:
  *** HEX DUMP
Server write IV:
  *** HEX DUMP
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { XXX, ··· XXX }
***
main, WRITE: TLSv1 Handshake, length = **
main, READ: TLSv1 Change Cipher Spec, length = **
main, READ: TLSv1 Handshake, length = **
*** Finished
verify_data:  { XXX, ··· XXX }
***
%% Cached client session: [Session-3, TLS_RSA_WITH_AES_128_CBC_SHA]
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = ****
main, READ: TLSv1 Application Data, length = ***
main, WRITE: TLSv1 Application Data, length = **
main, WRITE: TLSv1 Application Data, length = **
main, READ: TLSv1 Application Data, length = **
main, called close()
main, called closeInternal(true)
main, SEND TLSv1 ALERT:  warning, description = close_notify
main, WRITE: TLSv1 Alert, length = **
main, called closeSocket(selfInitiated)
Message sent!

之前的日志显示了两次失败的连接尝试,以及第三次成功的连接尝试。

EDIT 20160315: 正如下面评论者所提到的,exchange.*.com 主机似乎正在重定向到不同的主机,每个主机都有自己的证书,因为当提供带有 CN=smtpserver-ch-02 的证书时连接失败,而在提供带有 CN=smtpserver-ch-01 的证书时连接成功。

如果是这种情况,那么解决方案可能是多次运行 openssl 命令以检索这两个证书并将它们添加到信任库。

编辑(已解决):上述解决方案有效,我多次启动 openssl 命令,并比较结果数据,直到我分离出我需要的两个唯一证书。

将它们导入信任库后,一切正常。

【问题讨论】:

  • 服务器是否属于任何类型的集群、负载平衡或多租户系统,您的客户端指定的主机可能会解析为不同的服务?
  • @erickson 我不确定,作为服务器配置,无论是运行 Tomcat 服务器的 Linux 机器,还是交换 smtp 服务器,都由客户端处理,我只是管理部署的 Java应用程序。我唯一可以确定的是,尝试使用浏览器来检索 exchange.***.com 站点的证书不起作用,我必须通过带有 -starttls 选项的 openssl 来检索它,所以我猜有一个各种“内部”证书,交换地址是前端(虽然我不了解服务器配置)

标签: java email ssl smtp jakarta-mail


【解决方案1】:

您似乎从两个不同的服务器获得了两个不同的证书,因此您必须将它们都添加到您的信任库中。或者你可以设置mail.smtp.ssl.trust property

【讨论】:

  • 我真的很想避免诉诸验证异常,但似乎这是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2013-09-13
相关资源
最近更新 更多