https://www.boc.cn 握手失败

268 天前
 Hariz

Go client 请求 https://www.boc.cn 直接遇到 remote error: tls: handshake failure. 但是 Chrome 和 curl 都能正常返回。

查了半天没看出具体什么问题。有没有人遇到过这样情况的?谢谢!

Chrome: The connection to this site is encrypted and authenticated using TLS 1.2, RSA, and AES_256_CBC with HMAC-SHA1.

curl: SSL connection using TLSv1.2 / ECDHE-RSA-AES128-SHA256

*   Trying 2402:93c0:20::16:443...
*   Trying 219.141.191.47:443...
* Connected to www.boc.cn (2402:93c0:20::16) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: jurisdictionC=CN; jurisdictionST=Beijing; businessCategory=Private Organization; serialNumber=911000001000013428; C=CN; ST=Beijing; O=Bank of China Limited; CN=www.boc.cn
*  start date: Nov  1 00:00:00 2023 GMT
*  expire date: Nov 27 23:59:59 2024 GMT
*  subjectAltName: host "www.boc.cn" matched cert's "www.boc.cn"
*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=Secure Site Pro Extended Validation CA G2
*  SSL certificate verify ok.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /sourcedb/whpj/index.html HTTP/1.1
> Host: www.boc.cn
> User-Agent: curl/7.81.0
> Accept: */*
> 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
2807 次点击
所在节点    Go 编程语言
9 条回复
bv
268 天前
可能是通过 ja3 指纹
StarUDream
268 天前
用的是 `go1.22` 吧

更新日志里 `https://go.dev/doc/go1.22` 看一下 `crypto/tls`,加上环境变量 `GODEBUG=tls10server=1,tlsrsakex=1` 试试

如果加上环境变量可用,修改 `http.Client` 的 `tls.Config`:

```go
&tls.Config{
CipherSuites: tlsCipherSuites,
MinVersion: tls.VersionTLS10,
}

// copy from golang/1.22.1/go/src/crypto/tls/cipher_suites.go:270

var tlsCipherSuites = []uint16{
// AEADs w/ ECDHE
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,

// CBC w/ ECDHE
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,

// AEADs w/o ECDHE
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,

// CBC w/o ECDHE
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,

// 3DES
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
}
```
idontnowhat2say
268 天前
tcpdump 抓个包,看看是 handshake 哪个阶段失败的。
0o0O0o0O0o
268 天前
应该就是 #2 提到的问题
Hariz
268 天前
@StarUDream 谢谢!是#2 的问题
LoliconInside
268 天前
https://github.com/golang/go/issues/62459
go 1.22 开始指定默认 TLS 版本为 v1.2 ,但看起来#2 的方法是指定允许 TLS v1.0 的连接?
cURL 的执行结果显示支持 TLS v1.2 呀?迷惑
StarUDream
268 天前
StarUDream
268 天前
@LoliconInside

上面那段代码是直接搬过来用了,实际上根源是 1.22 版本中取消了基于 RSA 的加密方式,和 TLS 版本无关


```
// CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
// the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
//
// If CipherSuites is nil, a safe default list is used. The default cipher
// suites might change over time. In Go 1.22 RSA key exchange based cipher
// suites were removed from the default list, but can be re-added with the
// GODEBUG setting tlsrsakex=1.
CipherSuites []uint16
```
LoliconInside
268 天前
@StarUDream 明白了,感谢指教

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1028997

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX