V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Hariz
V2EX  ›  Go 编程语言

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

  •  
  •   Hariz · 248 天前 · 2780 次点击
    这是一个创建于 248 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    • Go 直接用的 &http.Client{} 没有任何配置
    • 中国银行用的是 DigiCert Inc 的 RSA 证书,看上去似乎也不是 CA 的问题?
    • 不知道是不是具体的 cipher suite 不匹配?好像也不像
    • 还能有什么可能的原因?

    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
    
    9 条回复    2024-04-02 16:50:27 +08:00
    bv
        1
    bv  
       248 天前
    可能是通过 ja3 指纹
    StarUDream
        2
    StarUDream  
       248 天前
    用的是 `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
        3
    idontnowhat2say  
       248 天前
    tcpdump 抓个包,看看是 handshake 哪个阶段失败的。
    0o0O0o0O0o
        4
    0o0O0o0O0o  
       248 天前 via iPhone
    应该就是 #2 提到的问题
    Hariz
        5
    Hariz  
    OP
       248 天前
    @StarUDream 谢谢!是#2 的问题
    LoliconInside
        6
    LoliconInside  
       248 天前
    https://github.com/golang/go/issues/62459
    go 1.22 开始指定默认 TLS 版本为 v1.2 ,但看起来#2 的方法是指定允许 TLS v1.0 的连接?
    cURL 的执行结果显示支持 TLS v1.2 呀?迷惑
    StarUDream
        7
    StarUDream  
       248 天前
    StarUDream
        8
    StarUDream  
       248 天前
    @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
        9
    LoliconInside  
       248 天前
    @StarUDream 明白了,感谢指教
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1078 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:16 · PVG 03:16 · LAX 11:16 · JFK 14:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.