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

如何用 golang 创建一个 https 服务用来获取来自浏览器的 tls 扩展信息?

  •  
  •   hygotest · 2023-03-02 12:00:45 +08:00 · 1157 次点击
    这是一个创建于 664 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我创建了一个类似这样的服务 package main

    import ( "crypto/tls" "log" "net" )

    func main() { cert, err := tls.LoadX509KeyPair("server.crt", "server.key") if err != nil { panic(err) }

    tlsConfig := &tls.Config{
    	// GetClientCertificate:     nil,
    	PreferServerCipherSuites: true,
    	CipherSuites: []uint16{
    		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
    		tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
    	},
    	MinVersion:             tls.VersionTLS12,
    	CurvePreferences:       []tls.CurveID{tls.CurveP256, tls.CurveP384, tls.CurveP521},
    	InsecureSkipVerify:     true,
    	SessionTicketsDisabled: true,
    	// ClientAuth:             tls.RequireAndVerifyClientCert,
    	Certificates: []tls.Certificate{cert},
    	ClientAuth:   tls.NoClientCert,
    	GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
    		return &cert, nil
    	},
    	GetClientCertificate: func(cri *tls.CertificateRequestInfo) (*tls.Certificate, error) {
    
    		return &cert, nil
    	},
    
    	// GetConfigForClient: func(ch *tls.ClientHelloInfo) (*tls.Config, error) {
    	// 	fmt.Println("GetConfigForClientHandler for:", ch.ServerName)
    	// 	// ja3.ComputeJA3FromSegment(ch.Context())
    	// 	return nil, nil
    	// },
    }
    // tlsConfig := tls.Config{Certificates: []tls.Certificate{cert}}
    
    listener, err := tls.Listen("tcp", ":8443", tlsConfig)
    if err != nil {
    	panic(err)
    }
    defer listener.Close()
    
    for {
    	conn, err := listener.Accept()
    	if err != nil {
    		log.Println(err)
    		continue
    	}
    	go handleConnection(conn)
    }
    

    }

    func handleConnection(conn net.Conn) { defer conn.Close()

    buf := make([]byte, 4096)
    for {
    	n, err := conn.Read(buf)
    	if err != nil {
    		log.Println(err)
    		return
    	}
    	log.Printf("Received %d bytes: %s", n, string(buf[:n]))
    }
    

    }

    我想计算浏览器的 ja3 指纹,按照 ja3 的格式,其他信息都可以拿到,目前只有 tls extensions (类似 negetiaion_info,application_settings )这部份信息拿不到,看资料说是 tls 准备库不支持! 请问有没有其他办法拿到?

    3 条回复    2023-03-02 17:12:54 +08:00
    cqcsdzmt
        1
    cqcsdzmt  
       2023-03-02 16:16:16 +08:00
    if conn, ok := c.(*tls.Conn); ok {
    for i, v := range conn.ConnectionState().PeerCertificates {
    //edit: use %X for uppercase hex printing
    log.Printf("cert %d sha1 fingerprint:%x \n", i, sha1.Sum(v.Raw))
    }
    }
    hygotest
        2
    hygotest  
    OP
       2023-03-02 17:05:24 +08:00
    @cqcsdzmt

    这个之前试过

    peerCertificates:
    []*crypto/x509.Certificate len: 0, cap: 0, nil


    但我证书是有效,而且我通过 wiresharke 抓包是可以获取这些 extensions list
    hygotest
        3
    hygotest  
    OP
       2023-03-02 17:12:54 +08:00
    补充下,我想要的不是证书的指纹,而 tls 指纹

    TLSVersion ,Ciphers ,Extensions ,EllipticCurves ,EllipticCurvePointFormats
    目前 Extensions 这个字段里的信息拿不到!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6042 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:53 · PVG 09:53 · LAX 17:53 · JFK 20:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.