我在本地机器上托管了一个apache james邮件服务器。它使用我添加到受信任列表中的自签名证书。我正在尝试使用java邮件发送和接收邮件
我得到这个错误:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
然而,SSL调试输出表明找到了受信任的证书。否则它不会告诉我太多。我还应该提到,这个邮件服务器与openssl以及雷鸟一起工作。
接收邮件代码:
String host = "192.168.1.21";
Boolean debug = true;
POP3Folder folder = null;
Store store = null;
try {
Properties props = new Properties();
props.put("mail.host", host);
props.put("mail.store.protocol", "pop3s");
props.put("mail.pop3s.port", "995");
Session session = Session.getInstance(props,null);
session.setDebug(debug);
store = session.getStore("pop3s");
store.connect(username, password);
当我尝试连接时会引发异常。
在过去的几个小时/几天里,我一直在用头撞墙,所以任何帮助都将不胜感激。
编辑:
SSL调试输出:
Info: ***
Info: Found trusted certificate:
Info: [
[
Version: V3
Subject: CN=192.168.1.21, OU=private, O=private, L=pretoria, ST=gauteng, C=za
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 2048 bits
modulus: 22201738425808301357843951429131863923295077691776461029270738957881925042102429206972015246280434827640419315658812269457485815395646018000726167885520466978079051879949885421741485411500412697981582621030362804785391242469536810788864680524659094190388912471585546967116467038492937424356023436763640787748242238829212068970215212531761712168559272937198654805596431568611192706600640030995533703350490664304506975658770991265086884832523665903150599863152070395170101007238711948275224105410201713594276436919539183706721126654808927498591115057177598201458589477257783098334024997797269658976390073190289972335957
public exponent: 65537
Validity: [From: Thu May 01 13:28:37 CAT 2014,
To: Wed Jul 30 13:28:37 CAT 2014]
Issuer: CN=192.168.1.21, OU=private, O=private, L=pretoria, ST=gauteng, C=za
SerialNumber: [ 618a1f7d]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 90 DF D4 14 E8 B7 70 38 28 F0 7F CC 83 60 3E 98 ......p8(....`>.
0010: DC EB 0B D5 ....
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 13 42 F1 F0 FB C4 A4 AD 1B 93 96 CE 53 64 72 4A .B..........SdrJ
0010: D2 C5 C7 66 18 BA 07 A6 C3 C6 97 9F E4 D1 8B 6F ...f...........o
0020: B9 72 3C F6 1C 3F 98 FB 3C 6C 74 A3 20 83 99 9A .r<..?..<lt. ...
0030: 9D 91 41 32 59 71 63 4A 3B 84 2E 2D 72 9F 2D AA ..A2YqcJ;..-r.-.
0040: 83 84 56 78 19 F9 8A AF DD 11 D5 C5 21 9E 93 06 ..Vx........!...
0050: 4D 48 2D 22 12 1F DA 1F 40 6A AD 9A 9A 29 4F 52 MH-"....@j...)OR
0060: 2D EB EB A7 13 B9 27 11 35 94 02 25 4E DF E5 6C -.....'.5..%N..l
0070: 6B 12 79 DD 22 E9 BB FE 20 34 4F B4 A1 CE E2 14 k.y."... 4O.....
0080: EE A4 B4 A8 D5 2D 9F 80 82 5E 71 03 49 B3 30 3C .....-...^q.I.0<
0090: 56 06 E3 62 2E 1C 5A E4 EE 15 4A 03 77 1C 94 4C V..b..Z...J.w..L
00A0: 20 D7 47 95 62 7F 21 22 CB 64 BF A0 34 D6 D5 AD .G.b.!".d..4...
00B0: 57 C1 A3 AD 69 70 DB 32 A5 B6 38 BB 1F 00 C7 5A W...ip.2..8....Z
00C0: 3A 73 3B 8D EE 2E A8 40 9A 24 D0 58 5C D5 A4 2D :s;....@.$.X\..-
00D0: 0F 09 2E DB 84 CF 55 21 79 C8 22 B5 2D E7 91 51 ......U!y.".-..Q
00E0: 05 8A 7D 1A 19 25 CC 30 EC 9B BA 77 78 9E 2E C9 .....%.0...wx...
00F0: 6C 2D F3 47 E9 44 1E 5A 41 92 14 11 9B E4 8E 59 l-.G.D.ZA......Y
]
Info: *** ServerHelloDone
Info: *** ClientKeyExchange, RSA PreMasterSecret, TLSv1
Info: http-listener-1(2), WRITE: TLSv1 Handshake, length = 262
Info: SESSION KEYGEN:
Info: PreMaster Secret:
Info: 0000:
Info: 03
//infos continue with things in between like CONNECTION KEYGEN: etc
//many more things like this
//continued
http-listener-1(2), WRITE: TLSv1 Change Cipher Spec, length = 1
Info: *** Finished
Info: verify_data: {
Info: 121
Info: ,
Info: 89
//many more infos
Info: }
Info: ***
Info: http-listener-1(2), WRITE: TLSv1 Handshake, length = 48
Info: http-listener-1(2), READ: TLSv1 Alert, length = 2
Info: http-listener-1(2)
Info: , RECV TLSv1 ALERT:
Info: fatal,
Info: handshake_failure
Info: %% Invalidated: [Session-2, TLS_RSA_WITH_AES_128_CBC_SHA]
Info: http-listener-1(2), called closeSocket()
Info: http-listener-1(2), handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
您是如何将证书添加到“受信任列表”的?
你见过这个JavaMailFAQ条目吗?
您还可以尝试将mail.pop3s.ssl.trust属性设置为"*"或服务器名称。
BTW,在您的代码中,您不需要设置mail.store协议或mail. pop3s.port。前者不需要,因为您将协议名称显式传递给getStore方法。后者不需要,因为它是“pop3s”协议的默认值。
我咨询了一位JSKSSL专家,他说:
日志中遗漏了太多东西,很难判断到底发生了什么。
服务器端的解密/删除/删除MAC操作似乎有问题。
他们取出了预言家秘密RSA最重要的字节(第二个):
Info: PreMaster Secret:
Info: 0000:
Info: 03
如果让我猜的话,我建议你试试:
java -Dcom.sun.net.ssl.rsaPreMasterSecretFix=true App
然后切换到false。
其他评论:
EJP似乎认为这是一次重新握手,唯一的提示是“Session-2”。在这个连接上可能有第二次握手,但是这些通常只在请求客户端身份验证的情况下完成,但是证书和ServerHelloDone之间没有证书请求,所以可能不是这样。
这很可能只是这个过程产生的第二个单独的连接。
这与信任无关,如果没有成功,握手不会通过ServerHelloDone。
在任何握手的情况下,客户端都会发送ChangeCipherSpec,然后下一个数据包是一个带有verify_data的已完成数据包,该数据包使用刚刚协商的密钥进行加密(48字节=4 Header 12verify_data20MAC12填充)。如果服务器无法正确解密/解压缩(AES-CBC)/解MAC,那么它将发回handshake_failure,情况似乎就是这样。
解密/删除/删除MAC操作似乎有问题。问题可能在服务器端(最有可能),或者他们在客户端安装了替代提供程序?