如何获取网站当前使用的密码套件?

huangapple go评论87阅读模式
英文:

How to get the currently used cipher suite of a website?

问题

你想要一个获取目标主机(例如:stackoverflow.com)当前使用的密码套件的程序。通常,你可以使用openssl命令来实现:openssl s_client -connect stackoverflow.com:443

输出结果如下:

CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = *.stackexchange.com
verify return:1
---
Certificate chain
 0 s:CN = *.stackexchange.com
   i:C = US, O = Let's Encrypt, CN = R3
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=CN = *.stackexchange.com

issuer=C = US, O = Let's Encrypt, CN = R3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 5138 bytes and written 360 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 27AFEC2CF0888EFFABF09081F331BA6B64FC5CD59FF8BD4A396CC0228E459EA6
    Session-ID-ctx: 
    Master-Key: 23F30C3F4FA581F3D1ACDC4B001859B8908469C03FEB4C26A9B34876DC13576A15B26260C7B00FB108DBF91CA16AC55E
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 06 ba da fe 3e 7f 04 6c-61 ee 97 f5 07 6a 9a 21   ....>..la....j.!
    0010 - e5 90 2c 8e c5 20 a2 fa-8c 2e 49 57 5e 55 4c f8   ..,.. ....IW^UL.
    0020 - b8 ac fa 34 8e 98 d0 76-90 76 cf b2 74 82 37 f0   ...4...v.v..t.7.
    0030 - b4 c2 1a d3 0e b6 f2 b3-4b 93 ec 2e ed 58 4d c8   ........K....XM.
    0040 - cd c9 63 ad 46 3e c9 77-1a 9f 5d c9 41 61 1b 56   ..c.F>.w..].Aa.V
    0050 - f4 d2 d0 f4 15 5e ad f6-e8 dd 00 11 74 4c 89 d8   .....^......tL..
    0060 - b2 7b 0c e5 d6 17 e4 9f-41 5e 2c 02 cd c5 74 20   .{......A^,...t 
    0070 - 82 ea 5f dc 52 bc 0a c7-69 13 50 a3 78 cd 0c 94   .._.R...i.P.x...
    0080 - 0c aa ad 33 b6 b0 26 63-20 6b ae 2e 1c 75 ef 79   ...3..&c k...u.y
    0090 - fc ee 54 a4 4f 86 d2 a8-72 83 c3 d2 1e 78 5d 8b   ..T.O...r....x].
    00a0 - 3e b1 e2 b8 bb 5d b5 b3-01 3b 3d 27 5d ba 40 1c   >....]...;='].@.
    00b0 - bd 11 2e 92 96 c5 ab 48-10 ac 47 e7 b0 db 79 d0   .......H..G...y.

    Start Time: 1646821102
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---

而ECDHE-RSA-AES128-GCM-SHA256正是我想要的结果。我想编写一个使用Go语言的程序,能够给出与openssl s_client -connect stackoverflow.com:443命令相同的输出结果。

以下是我的Go程序,但输出的密码套件似乎与openssl s_client -connect stackoverflow.com:443命令的结果不同。

package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"os"
)

var (
	targetHost, tlsVersion string
	TLS12Ciphers           = []uint16{
		tls.TLS_RSA_WITH_RC4_128_SHA,
		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
		tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
	}
	TLS13Ciphers = []uint16{
		tls.TLS_AES_128_GCM_SHA256,
		tls.TLS_AES_256_GCM_SHA384,
		tls.TLS_CHACHA20_POLY1305_SHA256,
	}
)

func showError(message string) {
	fmt.Println(message)
	os.Exit(0)
}

func supportedCiphers(targetHost string) []uint16 {
	var ciphersLists, supportedCiphers []uint16
	var tlsMinVer, tlsMaxVer int
	if tlsVersion == "1.2" {
		ciphersLists = TLS12Ciphers
		tlsMinVer = tls.VersionTLS10
		tlsMaxVer = tls.VersionTLS12
	} else if tlsVersion == "1.3" {
		ciphersLists = TLS13Ciphers
		tlsMinVer = tls.VersionTLS13
		tlsMaxVer = tls.VersionTLS13
	} else {
		showError("Invalid TLS version!")
	}
	for _, cipherSuite := range ciphersLists {
		tlsConfigs := &tls.Config{
			ServerName:   targetHost,
			CipherSuites: []uint16{cipherSuite},
			MinVersion:   uint16(tlsMinVer),
			MaxVersion:   uint16(tlsMaxVer),
		}
		conn, err := net.Dial("tcp", targetHost+":443")
		if err != nil {
			showError("Error when connecting to target server!")
		}
		tlsClient := tls.Client(conn, tlsConfigs)
		tlsClient.Handshake()
		tlsClient.Close()
		if tlsClient.ConnectionState().CipherSuite == cipherSuite {
			supportedCiphers = append(supportedCiphers, cipherSuite)
		}
	}
	return supportedCiphers
}

func main() {
	targetHost = os.Args[1]
	tlsVersion = os.Args[2]
	fmt.Println("Supported TLS " + tlsVersion + " ciphers")
	for _, cipherSuite := range supportedCiphers(targetHost) {
		fmt.Printf(tls.CipherSuiteName(cipherSuite) + "\n")
	}
}

请问如何编写一个Go程序,能够获取目标网站当前使用的密码套件,并给出与openssl s_client -connect stackoverflow.com:443命令相同的输出结果?

英文:

I want to get a cipher suite that currently used of any target host such as: stackoverflow.com. Normally, I would use an openssl command for this: openssl s_client -connect stackoverflow.com:443

Output:

CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = *.stackexchange.com
verify return:1
---
Certificate chain
0 s:CN = *.stackexchange.com
i:C = US, O = Let's Encrypt, CN = R3
1 s:C = US, O = Let's Encrypt, CN = R3
i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=CN = *.stackexchange.com
issuer=C = US, O = Let's Encrypt, CN = R3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 5138 bytes and written 360 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol  : TLSv1.2
Cipher    : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 27AFEC2CF0888EFFABF09081F331BA6B64FC5CD59FF8BD4A396CC0228E459EA6
Session-ID-ctx: 
Master-Key: 23F30C3F4FA581F3D1ACDC4B001859B8908469C03FEB4C26A9B34876DC13576A15B26260C7B00FB108DBF91CA16AC55E
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - 06 ba da fe 3e 7f 04 6c-61 ee 97 f5 07 6a 9a 21   ....>..la....j.!
0010 - e5 90 2c 8e c5 20 a2 fa-8c 2e 49 57 5e 55 4c f8   ..,.. ....IW^UL.
0020 - b8 ac fa 34 8e 98 d0 76-90 76 cf b2 74 82 37 f0   ...4...v.v..t.7.
0030 - b4 c2 1a d3 0e b6 f2 b3-4b 93 ec 2e ed 58 4d c8   ........K....XM.
0040 - cd c9 63 ad 46 3e c9 77-1a 9f 5d c9 41 61 1b 56   ..c.F>.w..].Aa.V
0050 - f4 d2 d0 f4 15 5e ad f6-e8 dd 00 11 74 4c 89 d8   .....^......tL..
0060 - b2 7b 0c e5 d6 17 e4 9f-41 5e 2c 02 cd c5 74 20   .{......A^,...t 
0070 - 82 ea 5f dc 52 bc 0a c7-69 13 50 a3 78 cd 0c 94   .._.R...i.P.x...
0080 - 0c aa ad 33 b6 b0 26 63-20 6b ae 2e 1c 75 ef 79   ...3..&c k...u.y
0090 - fc ee 54 a4 4f 86 d2 a8-72 83 c3 d2 1e 78 5d 8b   ..T.O...r....x].
00a0 - 3e b1 e2 b8 bb 5d b5 b3-01 3b 3d 27 5d ba 40 1c   >....]...;='].@.
00b0 - bd 11 2e 92 96 c5 ab 48-10 ac 47 e7 b0 db 79 d0   .......H..G...y.
Start Time: 1646821102
Timeout   : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: yes
---

And ECDHE-RSA-AES128-GCM-SHA256 is exactly the result I wanted. And I want to make a program that give the same output written in Go:
Input: the target host string
Output: the currently used cipher suite of that host
This is my Go program, but the output cipher suite doesn't seem to be the same as the openssl s_client -connect stackoverflow.com:443 command.

package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"os"
)

var (
	targetHost, tlsVersion string
	TLS12Ciphers           = []uint16{
		tls.TLS_RSA_WITH_RC4_128_SHA,
		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
		tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
	}
	TLS13Ciphers = []uint16{
		tls.TLS_AES_128_GCM_SHA256,
		tls.TLS_AES_256_GCM_SHA384,
		tls.TLS_CHACHA20_POLY1305_SHA256,
	}
)

func showError(message string) {
	fmt.Println(message)
	os.Exit(0)
}

func supportedCiphers(targetHost string) []uint16 {
	var ciphersLists, supportedCiphers []uint16
	var tlsMinVer, tlsMaxVer int
	if tlsVersion == "1.2" {
		ciphersLists = TLS12Ciphers
		tlsMinVer = tls.VersionTLS10
		tlsMaxVer = tls.VersionTLS12
	} else if tlsVersion == "1.3" {
		ciphersLists = TLS13Ciphers
		tlsMinVer = tls.VersionTLS13
		tlsMaxVer = tls.VersionTLS13
	} else {
		showError("Invalid TLS version!")
	}
	for _, cipherSuite := range ciphersLists {
		tlsConfigs := &tls.Config{
			ServerName:   targetHost,
			CipherSuites: []uint16{cipherSuite},
			MinVersion:   uint16(tlsMinVer),
			MaxVersion:   uint16(tlsMaxVer),
		}
		conn, err := net.Dial("tcp", targetHost+":443")
		if err != nil {
			showError("Error when connecting to target server!")
		}
		tlsClient := tls.Client(conn, tlsConfigs)
		tlsClient.Handshake()
		tlsClient.Close()
		if tlsClient.ConnectionState().CipherSuite == cipherSuite {
			supportedCiphers = append(supportedCiphers, cipherSuite)
		}
	}
	return supportedCiphers
}

func main() {
	targetHost = os.Args[1]
	tlsVersion = os.Args[2]
	fmt.Println("Supported TLS " + tlsVersion + " ciphers")
	for _, cipherSuite := range supportedCiphers(targetHost) {
		fmt.Printf(tls.CipherSuiteName(cipherSuite) + "\n")
	}
}

How can I make a Go program that get the currently used cipher suite of a target website and give the same output as the openssl s_client -connect stackoverflow.com:443 command?

答案1

得分: 1

目标网站的当前使用的密码套件是不明确的。没有"当前使用的密码套件":使用的密码是根据客户端和服务器根据它们宣布的偏好进行协商的。Go客户端有不同的偏好,因此会协商出不同的密码。请注意,OpenSSL也是如此:如果更改了OpenSSL的偏好设置,那么OpenSSL也会协商出不同的密码。

如果你想让你的Go代码"产生与openssl命令相同的输出",你需要调整Go的偏好设置、OpenSSL的偏好设置或两者兼而有之。例如,在你的Go代码中使用相同的密码(不宣布可用的ECDHE-RSA-AES128-GCM-SHA256)。

英文:

> the currently used cipher suite of a target website

is ill defined. There is no "currently used cipher suite": Which cipher is used is negotiated between the client and the server based on their announced preferences. The Go client has different preferences and thus negotiates a different cipher. Note that the same is true for OpenSSL: Ich you change your OpenSSL preferences then openssl will negotiate a different cipher too.

If you want to make your Go code "give the same output as the openssl [...] command" you will have to tweak the Go preferences, the OpenSSL preferences or both. E.g. by using the same ciphers in your Go code (which doesn't announce ECDHE-RSA-AES128-GCM-SHA256 as available).

huangapple
  • 本文由 发表于 2022年3月9日 18:39:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/71407990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定