我在使用http-kit向运行IIS7的Web服务器发送请求时遇到问题。当我打开调试模式时,我看到的就是在发送get请求之后,显然,我得到了几个小包和一堆“Ignoring unsupported cipher suite:”,然后是超时:
%% Cached client session: [Session-22, TLS_RSA_WITH_AES_128_CBC_SHA]
[read] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C A4 24 50 40 A5 F2 3B DD 01 BB 7C A2 .....$P@..;.....
Padded plaintext before ENCRYPTION: len = 208
0000: 47 45 54 20 2F ## ## ## ## ## ## ## ## ## ## ## GET /###########
0010: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0020: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0030: ## ## ## ## ## ## ## 20 48 54 54 50 2F 31 2E 31 ####### HTTP/1.1
0040: 0D 0A 48 6F 73 74 3A 20 ## ## ## ## ## ## ## ## ..Host: ########
0050: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0060: ## ## ## ## ## 0D 0A 55 73 65 72 2D 41 67 65 6E #####..User-Agen
0070: 74 3A 20 68 74 74 70 2D 6B 69 74 2F 32 2E 30 0D t: http-kit/2.0.
0080: 0A 41 63 63 65 70 74 2D 45 6E 63 6F 64 69 6E 67 .Accept-Encoding
0090: 3A 20 67 7A 69 70 2C 20 64 65 66 6C 61 74 65 0D : gzip, deflate.
00A0: 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A .Content-Length:
00B0: 20 30 0D 0A 0D 0A AF DD 9B 8A C3 9A BB BE 20 8B 0............ .
00C0: 94 AB 63 0F 74 80 4D 59 F4 73 05 05 05 05 05 05 ..c.t.MY.s......
client-loop, WRITE: TLSv1 Application Data, length = 182
[Raw write (bb)]: length = 213
0000: 17 03 01 00 D0 92 D5 AB 1C 3E 93 5F 45 C1 30 0D .........>._E.0.
0010: 25 6A 5F E7 67 06 2B 2B 2A B4 1E E5 7E EE 6C 96 %j_.g.++*.....l.
0020: F5 A6 D0 19 37 3E 30 9D 99 6B 8F 75 E3 35 16 02 ....7>0..k.u.5..
0030: 90 4E 6D 22 A5 FE FF 37 E9 DF 7C 38 25 4B 05 6D .Nm"...7...8%K.m
0040: CC 0A 8E 0E 3A 43 44 1F 23 83 D6 C4 4E B5 55 45 ....:CD.#...N.UE
0050: 58 7B 53 6E 03 2B 73 08 E6 EB 1E 49 75 B9 6E B4 X.Sn.+s....Iu.n.
0060: 2F 7D 6F 9A B2 B9 15 90 5F C7 82 67 98 39 AE 07 /.o....._..g.9..
0070: DC D0 53 B7 6C C2 C3 BE 7F 40 3F 73 DF 56 8A 3B ..S.l....@?s.V.;
0080: D2 A2 EF F7 16 AC 4E F9 4C 75 F8 B1 A6 3B 95 F6 ......N.Lu...;..
0090: 92 73 AF 84 C0 52 6A 08 77 8C A7 B1 18 A4 71 B7 .s...Rj.w.....q.
00A0: B6 8C 56 19 7A A1 12 6C E6 94 B0 84 C1 40 89 6D ..V.z..l.....@.m
00B0: B7 D5 8C F5 57 80 3E 19 2D 11 24 B3 88 A2 F5 9C ....W.>.-.$.....
00C0: FA 38 F9 D7 E8 1F 7B 7E 9F 72 68 BF 8C 82 D6 1E .8.......rh.....
00D0: B7 3D 33 06 98 .=3..
[Raw read]: length = 5
0000: 16 03 01 00 20 ....
[Raw read]: length = 32
0000: AA AA D1 B2 BE D1 00 84 C1 93 BF 8A 9A 77 ED 76 .............w.v
0010: 53 BB E0 3B 4B DB E6 A6 92 00 D0 2E 05 B7 4F EF S..;K.........O.
client-loop, READ: TLSv1 Handshake, length = 32
Padded plaintext after DECRYPTION: len = 32
0000: 00 00 00 00 C5 5C 82 7D 4D E6 C8 3D F5 2D F6 9F .....\..M..=.-..
0010: 64 B6 F9 DF 53 90 99 3F 07 07 07 07 07 07 07 07 d...S..?........
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: false
Is secure renegotiation: true
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
=>
{:opts {:sslengine #object[sun.security.ssl.SSLEngineImpl
0x7a21e0f7
"7a21e0f7[SSLEngine[hostname=null port=-1] TLS_RSA_WITH_AES_128_CBC_SHA]"],
:timeout 4000,
:method :get,
:url "https://################################################################################"},
:error #error{:cause "read timeout: 4000ms",
:via [{:type org.httpkit.client.TimeoutException,
:message "read timeout: 4000ms",
:at [org.httpkit.client.HttpClient clearTimeout "HttpClient.java" 82]}],
:trace [[org.httpkit.client.HttpClient clearTimeout "HttpClient.java" 82]
[org.httpkit.client.HttpClient run "HttpClient.java" 433]
[java.lang.Thread run "Thread.java" 745]]}}
实现这一目标的代码如下所示:
@(org.httpkit.client/get "https://################################################################################"
{:sslengine (build-ssl-engine (build-ssl-context {:keystore "####################" :keystore-pass "########"
:trust-store "####################" :trust-store-pass "########"
:protocol "TLSv1"}))
:timeout 4000})
辅助函数是:
(defn- setup-keystore ^KeyStore [file ^String password]
(let [keystore (KeyStore/getInstance "JKS")]
(with-open [inputstream (io/input-stream (io/resource file))]
(.load keystore inputstream (.toCharArray password)))
keystore))
(defn- key-managers [file ^String password]
(let [manager-factory (KeyManagerFactory/getInstance (KeyManagerFactory/getDefaultAlgorithm))]
(.init manager-factory (setup-keystore file password) (.toCharArray password))
(.getKeyManagers manager-factory)))
(defn- trust-managers [file password]
(let [manager-factory (TrustManagerFactory/getInstance (TrustManagerFactory/getDefaultAlgorithm))]
(.init manager-factory (setup-keystore file password))
(.getTrustManagers manager-factory)))
(defn build-ssl-context ^javax.net.ssl.SSLContext [{:keys [trust-store trust-store-pass keystore keystore-pass protocol]
:or {protocol "TLS"}}]
(let [key-managers (key-managers keystore keystore-pass)
trust-managers (trust-managers trust-store trust-store-pass)
ssl-context (SSLContext/getInstance protocol)]
(.init ssl-context key-managers trust-managers nil)
(SSLContext/setDefault ssl-context)
ssl-context))
(defn build-ssl-engine [^SSLContext ssl-context]
(doto (.createSSLEngine ssl-context)
(.setUseClientMode true)
(.setNeedClientAuth true)))
现在,我有一段类似但可行的Java代码。
%% Cached client session: [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
[read] MD5 and SHA1 hashes: len = 16
0000: 14 00 00 0C D2 53 C9 75 95 CC 0C E5 48 44 0E 7C .....S.u....HD..
Padded plaintext before ENCRYPTION: len = 240
0000: 47 45 54 20 ## ## ## ## ## ## ## ## ## ## ## ## GET /###########
0010: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0020: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0030: ## ## ## ## ## ## ## 20 48 54 54 50 2F 31 2E 31 ####### HTTP/1.1
0040: 0D 0A 55 73 65 72 2D 41 67 65 6E 74 3A 20 4A 61 ..User-Agent: Ja
0050: 76 61 2F 31 2E 38 2E 30 5F 31 31 32 0D 0A 48 6F va/1.8.0_112..Ho
0060: 73 74 3A 20 ## ## ## ## ## ## ## ## ## ## ## ## st: ############
0070: ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ################
0080: ## 0D 0A 41 63 63 65 70 74 3A 20 74 65 78 74 2F #..Accept: text/
0090: 68 74 6D 6C 2C 20 69 6D 61 67 65 2F 67 69 66 2C html, image/gif,
00A0: 20 69 6D 61 67 65 2F 6A 70 65 67 2C 20 2A 3B 20 image/jpeg, *;
00B0: 71 3D 2E 32 2C 20 2A 2F 2A 3B 20 71 3D 2E 32 0D q=.2, */*; q=.2.
00C0: 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 6B 65 65 .Connection: kee
00D0: 70 2D 61 6C 69 76 65 0D 0A 0D 0A 82 2E C5 FA E3 p-alive.........
00E0: B7 BC 64 D0 AE 36 F6 FE 0A E7 38 D3 0A 39 76 00 ..d..6....8..9v.
main, WRITE: TLSv1 Application Data, length = 240
[Raw write]: length = 245
0000: 17 03 01 00 F0 34 28 EC E7 31 92 96 43 E2 36 83 .....4(..1..C.6.
0010: AA 59 C1 CD EC 08 0D 8F 02 F0 3B 9D 3C 0A 65 73 .Y........;.<.es
0020: E7 FF 7E 08 5A 39 F2 16 AB 7F 02 CF B3 E4 A3 14 ....Z9..........
0030: 46 A4 EC 5A 1C B2 81 7B CA 65 78 5E DF 19 48 40 F..Z.....ex^..H@
0040: 2F 2B 0F D4 BB 6D 09 52 C6 14 BC C8 D2 C5 41 8A /+...m.R......A.
0050: 91 5F 90 53 A9 E3 15 21 2E 7C 8E 7B 2B E5 46 D6 ._.S...!....+.F.
0060: 9A 32 8F DF 35 49 6C 9A DA CB 02 BA BE 83 1D D3 .2..5Il.........
0070: 39 D6 C5 F4 E9 27 E9 1D A6 3F 0E BB C8 BE A0 6C 9....'...?.....l
0080: 32 97 BC FC 0C 04 68 8F CC 6B DA AF F2 40 2D 56 2.....h..k...@-V
0090: 47 EC 92 F5 36 19 FF F6 B4 97 31 9F 5D F0 75 31 G...6.....1.].u1
00A0: 12 6A AD D2 FA 95 22 A5 F7 D8 20 36 D9 F9 69 87 .j...."... 6..i.
00B0: 67 05 AE 97 68 81 8D C4 38 AC 74 6A B7 DB 51 DE g...h...8.tj..Q.
00C0: A2 65 86 F1 F4 F7 27 2C 3D 3C 85 BE DB 97 01 C7 .e....',=<......
00D0: 70 CE 19 FE D6 44 24 AE F3 38 79 C2 B9 DE 71 EB p....D$..8y...q.
00E0: 47 1A 3A 94 E8 3D F9 A0 DD 51 FD CE 01 84 E7 23 G.:..=...Q.....#
00F0: 8B F8 07 B2 2D ....-
[Raw read]: length = 5
0000: 16 03 01 00 20 ....
[Raw read]: length = 32
0000: E6 11 77 2F 9D 87 61 F5 FE 99 0D 62 51 7E D0 93 ..w/..a....bQ...
0010: 55 D2 4B B3 E8 91 DC F6 69 D8 2E 2E BF F4 B2 0F U.K.....i.......
main, READ: TLSv1 Handshake, length = 32
Padded plaintext after DECRYPTION: len = 32
0000: 00 00 00 00 43 53 ED 57 2D 63 29 89 E3 20 9C DD ....CS.W-c).. ..
0010: 17 58 AA E5 3D 13 BC BB 07 07 07 07 07 07 07 07 .X..=...........
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: false
Is secure renegotiation: true
*** HelloRequest (empty)
%% Client cached [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
%% Try resuming [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA] from port 57365
*** ClientHello, TLSv1
几乎相同的Java代码是:
public class Main {
public static void main(String[] args) {
try {
String keystore = "####################";
String keystorePassword = "########";
String trustStore = "####################";
String trustStorePassword = "########";
String protocol = "TLSv1";
buildSslContext(keystore, keystorePassword, trustStore, trustStorePassword, protocol);
URL url = new URL("https://################################################################################");
HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection();
httpsCon.setRequestMethod("GET");
String responseMessage = httpsCon.getResponseMessage();
System.out.printf("Response Message is %s\n", responseMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void buildSslContext(String keystore, String keystorePassword, String trustStore, String trustStorePassword, String protocol) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException {
SSLContext sslContext = SSLContext.getInstance(protocol);
KeyManager[] keyManagers = keyManagers(keystore, keystorePassword);
TrustManager[] trustManagers = trustManagers(trustStore, trustStorePassword);
sslContext.init(keyManagers, trustManagers, null);
SSLContext.setDefault(sslContext);
}
private static TrustManager[] trustManagers(String file, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
KeyStore trustStore = setupKeystore(file, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
return trustManagerFactory.getTrustManagers();
}
private static KeyManager[] keyManagers(String file, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException {
KeyStore keyStore = setupKeystore(file, password);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password.toCharArray());
return keyManagerFactory.getKeyManagers();
}
private static KeyStore setupKeystore(String file, String password) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
InputStream trustStoreUrl = new FileInputStream(file);
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(trustStoreUrl, password.toCharArray());
return trustStore;
}
}
最大的区别在于Clojure代码正在创建自己的SSLEngine,而Java代码似乎只是将SSLContext设置为默认代码。似乎Java从该Context创建了一个SSLEngine,而http-kit希望您提供它。请注意,我正在将其修复为TLSv1,因为如果我使用TLSv1.1或v1.2,则此IIS 7会终止连接。
有什么想法和/或如何修复它?
答案 0 :(得分:1)
我将在前面加上“我不是一个Clojure人”,但我认为您需要在SSLContext
代码中提供自己的http-kit
。有一个很好的blog post here讨论了如何使用名为less-awful-ssl
的Clojure库来生成SSLContext
并将其作为opts
地图提供给http-kit
请求方法(.createSSLEngine ctx)
将为您提供正确的SSLEngine
。
为了记录,当提供的密钥库没有RSA / DSA密钥或证书是证书时,我经常看到(即使在纯Java中)所有名义上支持的套件的“忽略不支持的密码套件”消息无效(即日期已过期等)。