add tls show cert

master
兔子 7 months ago
parent 572a6059bb
commit 54864722f2

@ -19,6 +19,7 @@ func init() {
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "dns", Use: "dns",
Aliases: []string{"dig"},
Short: "dns查询服务", Short: "dns查询服务",
Long: "DNS查询服务支持UDP,TCP,DoT,DoH", Long: "DNS查询服务支持UDP,TCP,DoT,DoH",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {

@ -29,6 +29,7 @@ import (
"b612.me/apps/b612/socks5" "b612.me/apps/b612/socks5"
"b612.me/apps/b612/split" "b612.me/apps/b612/split"
"b612.me/apps/b612/tcping" "b612.me/apps/b612/tcping"
"b612.me/apps/b612/tls"
"b612.me/apps/b612/uac" "b612.me/apps/b612/uac"
"b612.me/apps/b612/vic" "b612.me/apps/b612/vic"
"b612.me/apps/b612/whois" "b612.me/apps/b612/whois"
@ -40,7 +41,7 @@ import (
var cmdRoot = &cobra.Command{ var cmdRoot = &cobra.Command{
Use: "b612", Use: "b612",
Version: "2.1.0.beta", Version: "2.1.0.beta.4",
} }
func init() { func init() {
@ -49,7 +50,7 @@ func init() {
base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd, base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd,
ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd, ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd,
calc.Cmd, net.Cmd, rmt.Cmds, rmt.Cmdc, keygen.Cmd, dns.Cmd, whois.Cmd, socks5.Cmd, httproxy.Cmd, smtpserver.Cmd, smtpclient.Cmd, calc.Cmd, net.Cmd, rmt.Cmds, rmt.Cmdc, keygen.Cmd, dns.Cmd, whois.Cmd, socks5.Cmd, httproxy.Cmd, smtpserver.Cmd, smtpclient.Cmd,
cert.Cmd, aes.Cmd) cert.Cmd, aes.Cmd, tls.Cmd)
} }
func main() { func main() {

@ -0,0 +1,196 @@
package tls
import (
"b612.me/starlog"
"crypto/ecdsa"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/spf13/cobra"
"os"
"path/filepath"
"strings"
"time"
)
var hideDetail bool
var dump string
func init() {
Cmd.Flags().BoolVarP(&hideDetail, "hide-detail", "H", false, "隐藏证书详细信息")
Cmd.Flags().StringVarP(&dump, "dump", "d", "", "将证书保存到文件")
}
var Cmd = &cobra.Command{
Use: "tls",
Short: "查看TLS证书信息",
Long: "查看TLS证书信息",
Run: func(cmd *cobra.Command, args []string) {
for _, target := range args {
showTls(target, !hideDetail, dump)
}
},
}
func showTls(target string, showDetail bool, dumpPath string) {
if !strings.Contains(target, ":") {
target += ":443"
}
starlog.Infof("正在连接服务器: %s\n", target)
conn, err := tls.Dial("tcp", target, &tls.Config{
InsecureSkipVerify: true,
})
if err != nil {
starlog.Errorln("failed to connect: " + err.Error())
return
}
defer conn.Close()
starlog.Infoln("连接成功,正在获取证书信息")
certs := conn.ConnectionState().PeerCertificates
if len(certs) == 0 {
starlog.Errorln("no certificate found")
return
}
starlog.Infof("证书获取成功,证书链上共有%d个证书\n", len(certs))
if showDetail {
for _, c := range certs {
if c.IsCA {
continue
}
fmt.Printf("----------\n证书基础信息: %+v\n", c.Subject)
fmt.Printf("证书颁发者: %+v\n", c.Issuer)
fmt.Printf("证书生效时间: %+v 距今:%.1f天\n", c.NotBefore.In(time.Local), time.Since(c.NotBefore).Hours()/24)
fmt.Printf("证书过期时间: %+v 剩余:%.1f天\n", c.NotAfter.In(time.Local), c.NotAfter.Sub(time.Now()).Hours()/24)
fmt.Printf("证书序列号: %s\n", c.SerialNumber.Text(16))
fmt.Printf("证书签名算法: %s\n", c.SignatureAlgorithm)
fmt.Printf("证书公钥算法: %s\n", c.PublicKeyAlgorithm)
switch pub := c.PublicKey.(type) {
case *rsa.PublicKey:
fmt.Printf("RSA公钥位数: %d\n", pub.Size()*8) // RSA公钥的位数
case *ecdsa.PublicKey:
fmt.Printf("ECDSA Curve位数: %d\n", pub.Curve.Params().BitSize) // ECDSA公钥的位数
}
if len(c.DNSNames) != 0 {
fmt.Printf("可选使用的DNS: %s\n", strings.Join(c.DNSNames, ", "))
}
if len(c.IPAddresses) != 0 {
ipAddr := ""
for _, ip := range c.IPAddresses {
ipAddr += ip.String() + ", "
}
ipAddr = ipAddr[:len(ipAddr)-2]
fmt.Printf("可选使用的IP: %s\n", ipAddr)
}
if len(c.EmailAddresses) != 0 {
fmt.Printf("可选使用的Email: %s\n", strings.Join(c.EmailAddresses, ", "))
}
if len(c.URIs) != 0 {
fmt.Printf("可选使用的URI: %v\n", c.URIs)
}
if len(c.PermittedDNSDomains) != 0 {
fmt.Printf("批准使用的DNS: %s\n", strings.Join(c.PermittedDNSDomains, ", "))
}
if len(c.PermittedIPRanges) != 0 {
ipRange := ""
for _, ip := range c.PermittedIPRanges {
ipRange += ip.String() + ", "
}
ipRange = ipRange[:len(ipRange)-2]
fmt.Printf("批准使用的IP: %s\n", ipRange)
}
if len(c.PermittedEmailAddresses) != 0 {
fmt.Printf("批准使用的Email: %s\n", strings.Join(c.PermittedEmailAddresses, ", "))
}
if len(c.PermittedURIDomains) != 0 {
fmt.Printf("批准使用的URI: %s\n", strings.Join(c.PermittedURIDomains, ", "))
}
fmt.Printf("证书密钥用途: %s\n", strings.Join(KeyUsageToString(c.KeyUsage), ", "))
extKeyUsage := []string{}
for _, v := range c.ExtKeyUsage {
switch v {
case x509.ExtKeyUsageAny:
extKeyUsage = append(extKeyUsage, "任何用途")
case x509.ExtKeyUsageServerAuth:
extKeyUsage = append(extKeyUsage, "服务器认证")
case x509.ExtKeyUsageClientAuth:
extKeyUsage = append(extKeyUsage, "客户端认证")
case x509.ExtKeyUsageCodeSigning:
extKeyUsage = append(extKeyUsage, "代码签名")
case x509.ExtKeyUsageEmailProtection:
extKeyUsage = append(extKeyUsage, "电子邮件保护")
case x509.ExtKeyUsageIPSECEndSystem:
extKeyUsage = append(extKeyUsage, "IPSEC终端系统")
case x509.ExtKeyUsageIPSECTunnel:
extKeyUsage = append(extKeyUsage, "IPSEC隧道")
case x509.ExtKeyUsageIPSECUser:
extKeyUsage = append(extKeyUsage, "IPSEC用户")
case x509.ExtKeyUsageTimeStamping:
extKeyUsage = append(extKeyUsage, "时间戳")
case x509.ExtKeyUsageOCSPSigning:
extKeyUsage = append(extKeyUsage, "OCSP签名")
case x509.ExtKeyUsageMicrosoftServerGatedCrypto:
extKeyUsage = append(extKeyUsage, "Microsoft服务器门控加密")
case x509.ExtKeyUsageNetscapeServerGatedCrypto:
extKeyUsage = append(extKeyUsage, "Netscape服务器门控加密")
case x509.ExtKeyUsageMicrosoftCommercialCodeSigning:
extKeyUsage = append(extKeyUsage, "Microsoft商业代码签名")
case x509.ExtKeyUsageMicrosoftKernelCodeSigning:
extKeyUsage = append(extKeyUsage, "Microsoft内核代码签名")
default:
extKeyUsage = append(extKeyUsage, fmt.Sprintf("未知用途(%d)", v))
}
}
fmt.Printf("证书扩展密钥用途: %s\n", strings.Join(extKeyUsage, ", "))
fmt.Printf("证书版本: %d\n", c.Version)
//fmt.Printf("证书扩展信息: %+v\n\n----------", c.Extensions)
}
if dumpPath != "" {
var data []byte
var name string
for _, c := range certs {
if name == "" {
name = c.Subject.CommonName + ".crt"
}
certBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: c.Raw,
}
data = append(data, pem.EncodeToMemory(certBlock)...)
}
err = os.WriteFile(filepath.Join(dumpPath, name), data, 0644)
if err != nil {
starlog.Errorln("failed to write file: " + err.Error())
return
}
starlog.Infoln("dumped to " + filepath.Join(dumpPath, name))
}
}
}
func KeyUsageToString(ku x509.KeyUsage) []string {
usages := []string{}
flags := []struct {
Flag x509.KeyUsage
Name string
}{
{x509.KeyUsageDigitalSignature, "数字签名"},
{x509.KeyUsageContentCommitment, "内容承诺"},
{x509.KeyUsageKeyEncipherment, "密钥加密"},
{x509.KeyUsageDataEncipherment, "数据加密"},
{x509.KeyUsageKeyAgreement, "密钥协商"},
{x509.KeyUsageCertSign, "证书签名"},
{x509.KeyUsageCRLSign, "CRL签名"},
{x509.KeyUsageEncipherOnly, "仅加密"},
{x509.KeyUsageDecipherOnly, "仅解密"},
}
for _, flag := range flags {
if ku&flag.Flag != 0 {
usages = append(usages, flag.Name)
}
}
return usages
}

@ -0,0 +1,7 @@
package tls
import "testing"
func TestCert(t *testing.T) {
showTls("139.199.163.65:443", true, "")
}
Loading…
Cancel
Save