我似乎无法掌握 SSL 的工作方式……或者至少我无法解释 java 的 ssl 调试输出,所以我(计划)这样做:客户端和服务器生成自己的密钥对和自签名证书。(我只需要在重新连接时确保身份。)为了测试,我在服务器和客户端都使用相同的密钥和信任(只有一个密钥和证书)。握手过程中出了点问题,但我不明白错误消息。阅读了大约 20 个论坛和有关此的帖子,但到目前为止还没有弄清楚。那么有人可以告诉我底部的这条消息到底是什么意思吗?如果您需要更多详细信息,请告诉我。谢谢!
服务器 SSL 调试
trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable 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_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
EndpointIdentificationAlgorithm: null
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
[Raw read]: length = 5
0000: 16 03 01 00 95 .....
[Raw read]: length = 149
0000: 01 00 00 91 03 01 51 0F F6 C7 F3 99 F4 4B 77 A8 ......Q......Kw.
0010: 43 BB A0 89 E0 D9 20 4D 9F 5A C2 E2 0E 80 87 9F C..... M.Z......
0020: 59 9A 13 71 F7 4F 00 00 2A 00 33 C0 04 00 16 00 Y..q.O..*.3.....
0030: 05 C0 03 C0 11 C0 02 C0 07 C0 13 C0 08 C0 0C 00 ................
0040: FF C0 0D C0 0E C0 09 00 2F C0 12 00 04 00 32 00 ......../.....2.
0050: 13 00 0A 01 00 00 3E 00 0A 00 34 00 32 00 17 00 ......>...4.2...
0060: 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 ................
0070: 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 ................
0080: 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 ................
0090: 0B 00 02 01 00 .....
New I/O worker #1, READ: TLSv1 Handshake, length = 149
*** ClientHello, TLSv1
RandomCookie: GMT: 1359934919 bytes = { 243, 153, 244, 75, 119, 168, 67, 187, 160, 137, 224, 217, 32, 77, 159, 90, 194, 226, 14, 128, 135, 159, 89, 154, 19, 113, 247, 79 }
Session ID: {}
Cipher Suites: [TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[read] MD5 and SHA1 hashes: len = 149
0000: 01 00 00 91 03 01 51 0F F6 C7 F3 99 F4 4B 77 A8 ......Q......Kw.
0010: 43 BB A0 89 E0 D9 20 4D 9F 5A C2 E2 0E 80 87 9F C..... M.Z......
0020: 59 9A 13 71 F7 4F 00 00 2A 00 33 C0 04 00 16 00 Y..q.O..*.3.....
0030: 05 C0 03 C0 11 C0 02 C0 07 C0 13 C0 08 C0 0C 00 ................
0040: FF C0 0D C0 0E C0 09 00 2F C0 12 00 04 00 32 00 ......../.....2.
0050: 13 00 0A 01 00 00 3E 00 0A 00 34 00 32 00 17 00 ......>...4.2...
0060: 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 ................
0070: 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 ................
0080: 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 ................
0090: 0B 00 02 01 00 .....
%% Initialized: [Session-1, SSL_NULL_WITH_NULL_NULL]
keymanager chooseEngineServerAlias
keymanager getPrivateKey: 3eb9936d-2240-4687-bf4e-6518460e3e40
keymanager getCertificateChain: 3eb9936d-2240-4687-bf4e-6518460e3e40
%% Negotiating: [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
*** ServerHello, TLSv1
RandomCookie: GMT: 1359934920 bytes = { 242, 252, 196, 36, 227, 154, 97, 148, 214, 170, 109, 188, 122, 223, 161, 62, 131, 201, 214, 11, 223, 36, 74, 224, 72, 78, 94, 50 }
Session ID: {81, 15, 246, 200, 127, 240, 115, 234, 52, 13, 73, 40, 137, 163, 243, 8, 51, 244, 147, 87, 128, 39, 210, 175, 163, 244, 86, 238, 138, 87, 29, 43}
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
Cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=3eb9936d-2240-4687-bf4e-6518460e3e40
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 1024 bits
modulus: 130292698947319747550411805428932496764788133931614615268432511412918979081774531703795353050388491281785406619160787220723201364083891450242081089010992812611565317265297099663990262828027908909326882453616292013722474448961222856631109497585792129874215397389474004374746492345728806709616072944360825031857
public exponent: 65537
Validity: [From: Sun Feb 03 03:52:37 CET 2013,
To: Wed Feb 01 03:52:37 CET 2023]
Issuer: CN=3eb9936d-2240-4687-bf4e-6518460e3e40
SerialNumber: [ 1bd22c7d 61d1a1eb]
]
Algorithm: [SHA1withRSA]
Signature:
0000: 94 5E 4F 74 28 A7 6C 94 25 60 4B 38 9F 7F 2D DE .^Ot(.l.%`K8..-.
0010: 6D 3E E5 1F 55 E4 F2 14 3F 80 FF D4 24 55 B9 60 m>..U...?...$U.`
0020: 4C C3 B6 BB 68 CD 12 AD FA BA 6D B0 76 5F 91 96 L...h.....m.v_..
0030: 08 97 9D 53 E8 28 5C DE 69 DD 30 92 F1 FE 59 21 ...S.(\.i.0...Y!
0040: 81 05 E6 E6 8D 89 6E 77 A4 6A EC 13 E5 0B D9 17 ......nw.j......
0050: 03 51 85 FB 14 D8 FA 6A A3 52 71 57 F2 A5 CC 80 .Q.....j.RqW....
0060: 31 6D EA 64 81 4F C9 53 AC 01 FA EF AF 9D 0A F0 1m.d.O.S........
0070: 9F 67 1E 76 D7 41 C9 62 2B 5B FB 42 E1 AF 55 F8 .g.v.A.b+[.B..U.
]
***
*** Diffie-Hellman ServerKeyExchange
DH Modulus: { 233, 230, 66, 89, 157, 53, 95, 55, 201, 127, 253, 53, 103, 18, 11, 142, 37, 201, 205, 67, 233, 39, 179, 169, 103, 15, 190, 197, 216, 144, 20, 25, 34, 210, 195, 179, 173, 36, 128, 9, 55, 153, 134, 157, 30, 132, 106, 171, 73, 250, 176, 173, 38, 210, 206, 106, 34, 33, 157, 71, 11, 206, 125, 119, 125, 74, 33, 251, 233, 194, 112, 181, 127, 96, 112, 2, 243, 206, 248, 57, 54, 148, 207, 69, 238, 54, 136, 193, 26, 140, 86, 171, 18, 122, 61, 175 }
DH Base: { 48, 71, 10, 213, 160, 5, 251, 20, 206, 45, 157, 205, 135, 227, 139, 199, 209, 177, 197, 250, 203, 174, 203, 233, 95, 25, 10, 167, 163, 29, 35, 196, 219, 188, 190, 6, 23, 69, 68, 64, 26, 91, 44, 2, 9, 101, 216, 194, 189, 33, 113, 211, 102, 132, 69, 119, 31, 116, 186, 8, 77, 32, 41, 216, 60, 28, 21, 133, 71, 243, 169, 241, 162, 113, 91, 226, 61, 81, 174, 77, 62, 90, 31, 106, 112, 100, 243, 22, 147, 58, 52, 109, 63, 82, 146, 82 }
Server DH Public Key: { 73, 233, 14, 202, 89, 13, 188, 236, 57, 124, 97, 186, 86, 30, 193, 15, 117, 169, 125, 103, 204, 9, 145, 52, 184, 3, 58, 205, 66, 147, 131, 141, 40, 92, 208, 244, 197, 165, 243, 13, 18, 43, 68, 74, 135, 150, 21, 31, 181, 224, 98, 239, 200, 95, 130, 97, 202, 11, 152, 181, 123, 206, 248, 248, 146, 117, 167, 55, 30, 106, 64, 247, 45, 147, 134, 46, 36, 96, 50, 200, 140, 102, 166, 231, 229, 207, 210, 48, 211, 107, 181, 111, 6, 113, 57, 195 }
Signed with a DSA or RSA public key
New I/O worker #1, fatal error: 80: problem unwrapping net record
java.lang.RuntimeException: Delegated task threw Exception/Error
%% Invalidated: [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]
New I/O worker #1, SEND TLSv1 ALERT: fatal, description = internal_error
New I/O worker #1, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 50 ......P
New I/O worker #1, called closeOutbound()
New I/O worker #1, closeOutboundInternal()
客户端 SSL 调试
testClient
trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable 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_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
client.start(): true
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_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 unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
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 unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
%% No cached client session
*** ClientHello, TLSv1
RandomCookie: GMT: 1360012393 bytes = { 134, 128, 126, 2, 241, 35, 109, 215, 218, 46, 141, 218, 44, 43, 228, 29, 9, 155, 72, 100, 59, 29, 177, 236, 197, 205, 21, 138 }
Session ID: {}
Cipher Suites: [TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes: len = 149
0000: 01 00 00 91 03 01 51 10 24 69 86 80 7E 02 F1 23 ......Q.$i.....#
0010: 6D D7 DA 2E 8D DA 2C 2B E4 1D 09 9B 48 64 3B 1D m.....,+....Hd;.
0020: B1 EC C5 CD 15 8A 00 00 2A 00 33 C0 04 00 16 00 ........*.3.....
0030: 05 C0 03 C0 11 C0 02 C0 07 C0 13 C0 08 C0 0C 00 ................
0040: FF C0 0D C0 0E C0 09 00 2F C0 12 00 04 00 32 00 ......../.....2.
0050: 13 00 0A 01 00 00 3E 00 0A 00 34 00 32 00 17 00 ......>...4.2...
0060: 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 ................
0070: 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 ................
0080: 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 ................
0090: 0B 00 02 01 00 .....
pool-5-thread-2, WRITE: TLSv1 Handshake, length = 149
[Raw write]: length = 154
0000: 16 03 01 00 95 01 00 00 91 03 01 51 10 24 69 86 ...........Q.$i.
0010: 80 7E 02 F1 23 6D D7 DA 2E 8D DA 2C 2B E4 1D 09 ....#m.....,+...
0020: 9B 48 64 3B 1D B1 EC C5 CD 15 8A 00 00 2A 00 33 .Hd;.........*.3
0030: C0 04 00 16 00 05 C0 03 C0 11 C0 02 C0 07 C0 13 ................
0040: C0 08 C0 0C 00 FF C0 0D C0 0E C0 09 00 2F C0 12 ............./..
0050: 00 04 00 32 00 13 00 0A 01 00 00 3E 00 0A 00 34 ...2.......>...4
0060: 00 32 00 17 00 01 00 03 00 13 00 15 00 06 00 07 .2..............
0070: 00 09 00 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E ................
0080: 00 0F 00 10 00 11 00 02 00 12 00 04 00 05 00 14 ................
0090: 00 08 00 16 00 0B 00 02 01 00 ..........
[Raw read]: length = 5
0000: 15 03 01 00 02 .....
[Raw read]: length = 2
0000: 02 50 .P
New I/O worker #1, READ: TLSv1 Alert, length = 2
New I/O worker #1, RECV TLSv1 ALERT: fatal, internal_error
New I/O worker #1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: internal_error
New I/O worker #1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: internal_error
New I/O worker #1, called closeOutbound()
New I/O worker #1, closeOutboundInternal()
New I/O worker #1, SEND TLSv1 ALERT: warning, description = close_notify
New I/O worker #1, WRITE: TLSv1 Alert, length = 2
New I/O worker #1, called closeInbound()
New I/O worker #1, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
[Raw write]: length = 7
0000: 15 03 01 00 02 01 00 .......
main, called closeOutbound()
main, closeOutboundInternal()
New I/O worker #1, called closeOutbound()
New I/O worker #1, closeOutboundInternal()
Security.java(对所有安全相关的东西进行分组)
public class Security
{
private static final String protocol = "TLS";
@SuppressWarnings("restriction")
private static X509Certificate generateCertificate(String dn, KeyPair pair, String algorithm) throws GeneralSecurityException, IOException
{
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + 10l * 365 * 24 * 60 * 60 * 1000);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert to identify the algorithm that's used.
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
// Update the algorith, and resign.
algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
return cert;
}
protected static char[] getPassword()
{
return "test".toCharArray();
}
private static void pushKeyStoreToConfig(KeyStore ks, String configKey) throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ks.store(baos, Security.getPassword());
Configuration.set(configKey, baos.toByteArray());
}
private KeyManager[] keyManagers;
private KeyStore keyStore;
private KeyStore trustStore;
private SSLContext sslContext;
private TrustManager[] trustManagers;
public Security()
{
LoggerFactory.getLogger(Security.class).debug("constructing...");
}
public synchronized void addCertificate(String guid, Certificate certificate) throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException
{
this.getTrustStore().setCertificateEntry(guid, certificate);
Security.pushKeyStoreToConfig(this.getTrustStore(), Configuration.TRUST_STORE);
Configuration.getInstance().save();
}
public SslHandler createSslHandler()
{
SSLEngine engine = this.getSslContext().createSSLEngine();
engine.setUseClientMode(true);
engine.setNeedClientAuth(true);
return new SslHandler(engine);
}
public synchronized KeyManager[] getKeyManagers()
{
if (this.keyManagers == null)
{
KeyManager keyManager = new X509ExtendedKeyManager()
{
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
{
System.out.println("keymanager chooseClientAlias");
return Configuration.get(Configuration.GUID, String.class);
}
@Override
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine)
{
System.out.println("keymanager chooseEngineClientAlias");
return Configuration.get(Configuration.GUID, String.class);
}
@Override
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
{
System.out.println("keymanager chooseEngineServerAlias");
return Configuration.get(Configuration.GUID, String.class);
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
{
System.out.println("keymanager chooseServerAlias");
return Configuration.get(Configuration.GUID, String.class);
}
@Override
public X509Certificate[] getCertificateChain(String alias)
{
System.out.println("keymanager getCertificateChain: " + alias);
try
{
Certificate[] certs = Security.this.getKeyStore().getCertificateChain(alias);
X509Certificate[] xcerts = new X509Certificate[certs.length];
for (int i = 0; i < certs.length; i++)
{
xcerts[i] = (X509Certificate) certs[i];
}
return xcerts;
}
catch (Exception e)
{
LoggerFactory.getLogger(Security.class).error("Error while getting security chain", e);
return null;
}
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers)
{
System.out.println("keymanager getClientAliases");
// TODO Auto-generated method stub
return null;
}
@Override
public PrivateKey getPrivateKey(String alias)
{
System.out.println("keymanager getPrivateKey: " + alias);
try
{
return (PrivateKey) Security.this.getKeyStore().getKey(alias, Security.getPassword());
}
catch (Exception e)
{
LoggerFactory.getLogger(Security.class).error("Error while getting private key", e);
return null;
}
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers)
{
System.out.println("keymanager getServerAliases");
// TODO Auto-generated method stub
return null;
}
};
this.keyManagers = new KeyManager[] { keyManager };
}
return this.keyManagers;
}
public synchronized KeyStore getKeyStore() throws IOException, GeneralSecurityException
{
if (this.keyStore == null)
{
this.keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
try
{
ByteArrayInputStream bais = new ByteArrayInputStream(Configuration.get(Configuration.KEY_STORE, byte[].class));
this.keyStore.load(bais, Security.getPassword());
}
catch (Exception e)
{
LoggerFactory.getLogger(Security.class).warn("Could not load key store, creating new one", e);
this.keyStore.load(null);
}
String guid = Configuration.get(Configuration.GUID, String.class);
if (this.keyStore.getKey(guid, Security.getPassword()) == null)
{
this.resetKey(this.keyStore);
}
// TODO certificate expired? create new one!
}
return this.keyStore;
}
public synchronized SSLContext getSslContext()
{
if (this.sslContext == null)
{
SSLContext context = null;
try
{
context = SSLContext.getInstance(Security.protocol);
context.init(this.getKeyManagers(), this.getTrustManagers(), Controller.getInstance().getRandom());
}
catch (Exception e)
{
throw new Error("Failed to initialize the server-side SSLContext", e);
}
this.sslContext = context;
}
return this.sslContext;
}
private synchronized TrustManager[] getTrustManagers()
{
if (this.trustManagers == null)
{
TrustManager trustManager = new X509TrustManager()
{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
System.out.println("trustmanager checkClientTrusted");
this.checkTrusted(chain, authType);
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
System.out.println("trustmanager checkServerTrusted");
this.checkTrusted(chain, authType);
}
public void checkTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
Certificate cert = null;
try
{
cert = Security.this.getTrustStore().getCertificate(chain[0].getSubjectX500Principal().getName());
if (cert == null)
{
throw new CertificateException("Certificate is not trusted: " + chain[0]);
}
}
catch (Exception e)
{
throw new CertificateException("Error while validating certificate: " + chain[0], e);
}
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
};
this.trustManagers = new TrustManager[] { trustManager };
}
return this.trustManagers;
}
protected synchronized KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
{
if (this.trustStore == null)
{
this.trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
try
{
this.trustStore.load(new ByteArrayInputStream(Configuration.get(Configuration.TRUST_STORE, byte[].class)), Security.getPassword());
}
catch (Exception e)
{
LoggerFactory.getLogger(Security.class).warn("Could not load trust store, creating new one", e);
this.trustStore.load(null);
}
}
return this.trustStore;
}
public synchronized void resetKey() throws IOException, GeneralSecurityException
{
this.resetKey(this.getKeyStore());
}
private synchronized void resetKey(KeyStore ks) throws IOException, GeneralSecurityException
{
LoggerFactory.getLogger(Security.class).info("Creating a new key pair and certificate");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024, Controller.getInstance().getRandom());
KeyPair kp = kpg.generateKeyPair();
PrivateKey key = kp.getPrivate();
String dn = "cn=" + Configuration.get(Configuration.GUID, String.class);
X509Certificate[] chain = new X509Certificate[] { Security.generateCertificate(dn, kp, "SHA1withRSA") };
ks.setKeyEntry(Configuration.get(Configuration.GUID, String.class), key, Security.getPassword(), chain);
Security.pushKeyStoreToConfig(ks, Configuration.KEY_STORE);
this.addCertificate(Configuration.get(Configuration.GUID, String.class), chain[0]);
}
}
附加信息
在服务器引擎的情况下从外部设置 setUseClientMode()。