最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang實(shí)現(xiàn)檢測(cè)SSL證書有效期

 更新時(shí)間:2026年04月20日 09:41:42   作者:彭世瑜  
本文主要為大家詳細(xì)介紹如何使用Go語言中的crypto/tls模塊來獲取網(wǎng)站的SSL/TLS證書信息并檢查其有效期,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

原理:使用go提供的模塊 crypto/tls,可以獲取域名證書的信息,通過到期時(shí)間可以判斷證書是否過期

package main

import (
	"crypto/tls"
	"fmt"
)

func main() {
	conn, _ := tls.Dial("tcp", "www.baidu.com:443", nil)
	cert := conn.ConnectionState().PeerCertificates[0]

	// 時(shí)間信息
	fmt.Printf("NotBefore: %v\n", cert.NotBefore)
	// NotBefore: 2022-07-05 05:16:02 +0000 UTC

	fmt.Printf("NotAfter: %v\n", cert.NotAfter)
	// NotAfter: 2023-08-06 05:16:01 +0000 UTC

	// 其他信息
	fmt.Printf("IPAddresses: %v\n", cert.IPAddresses)
	// IPAddresses: []
	fmt.Printf("IPAddresses: %v\n", conn.RemoteAddr())
	// IPAddresses: 220.181.38.150:443
	fmt.Printf("Version: %v\n", cert.Version)
	fmt.Printf("SerialNumber: %v\n", cert.SerialNumber)
	fmt.Printf("Issuer: %v\n", cert.Issuer)
	fmt.Printf("Subject: %v\n", cert.Subject)
}

方法補(bǔ)充

方法一:

在 Go 語言中檢測(cè) SSL 證書是否到期,最常用的方法是利用標(biāo)準(zhǔn)庫 crypto/tls 主動(dòng)與服務(wù)器建立一次 TLS 連接,以此獲取證書鏈,然后從證書的 NotAfter 字段解析出到期時(shí)間。

下面是一個(gè)通用函數(shù) CheckSSLCertExpiry 的完整實(shí)現(xiàn),它接受域名,返回證書的剩余有效天數(shù)和可能的錯(cuò)誤。

package main
import (
    "crypto/tls"
    "fmt"
    "net"
    "time"
)
// CheckSSLCertExpiry 檢查給定域名的 SSL 證書有效期,返回剩余天數(shù)
func CheckSSLCertExpiry(domain string) (int, error) {
    // 1. 配置 tls.Config
    // InsecureSkipVerify: true 用來繞過證書本身的校驗(yàn),否則證書過期或無效時(shí)連接會(huì)失敗,我們反而拿不到證書信息。
    // ServerName: 顯式設(shè)置 SNI,對(duì)于使用 CDN 的網(wǎng)站尤其重要,以防止獲取到錯(cuò)誤的默認(rèn)證書。
    conf := &tls.Config{
        InsecureSkipVerify: true,
        ServerName:         domain,
    }
    // 2. 建立 TLS 連接
    // 設(shè)置一個(gè)連接超時(shí),防止網(wǎng)絡(luò)問題導(dǎo)致程序長(zhǎng)時(shí)間阻塞。
    dialer := &net.Dialer{Timeout: 10 * time.Second}
    conn, err := tls.DialWithDialer(dialer, "tcp", fmt.Sprintf("%s:443", domain), conf)
    if err != nil {
        return 0, fmt.Errorf("failed to connect to %s: %w", domain, err)
    }
    defer conn.Close()
    // 3. 獲取證書鏈
    // PeerCertificates 返回的是對(duì)端發(fā)送的證書鏈,第一個(gè)元素 (索引0) 通常是服務(wù)器本身的證書(葉子證書)。
    certs := conn.ConnectionState().PeerCertificates
    if len(certs) == 0 {
        return 0, fmt.Errorf("no certificates found for %s", domain)
    }
    leafCert := certs[0]
    // 4. 計(jì)算剩余天數(shù)
    // NotAfter 是 UTC 時(shí)間,time.Now() 返回的是本地時(shí)間,但 Go 的 time 包在比較時(shí)會(huì)自動(dòng)轉(zhuǎn)換到同一時(shí)區(qū),所以直接相減是安全的。
    // 使用 math.Ceil 確保剩余天數(shù)向上取整,避免因精度問題將 "剩余0.9天" 顯示為 "0天"。
    remaining := time.Until(leafCert.NotAfter)
    days := int(remaining.Hours() / 24)
    if remaining.Hours() > 0 && days == 0 {
        days = 1
    }
    return days, nil
}
func main() {
    // 示例:檢查 example.com 的證書有效期
    domain := "www.baidu.com"
    days, err := CheckSSLCertExpiry(domain)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("SSL certificate for %s is valid for %d more days.\n", domain, days)
}

代碼核心邏輯解讀

你可以對(duì)照上面代碼中的注釋,理解關(guān)鍵步驟:

  • tls.Config 配置:通過 InsecureSkipVerify: true 讓連接跳過常規(guī)驗(yàn)證,這樣即使是過期或無效的證書也能建立連接,以便我們獲取信息。同時(shí)設(shè)置 ServerName 指定了 SNI,這對(duì)于使用 CDN 的域名非常關(guān)鍵。
  • 建立連接:使用 tls.DialWithDialer 替代 tls.Dial 可以方便地設(shè)置連接超時(shí)。
  • 獲取證書conn.ConnectionState().PeerCertificates 返回證書鏈,其中第一個(gè)元素(索引 0)通常就是該域名的“葉子證書”。
  • 計(jì)算天數(shù):用 time.Until(cert.NotAfter) 計(jì)算剩余時(shí)間,并通過 remaining.Hours()/24 得到剩余天數(shù)。

注意事項(xiàng)

  • 關(guān)于 InsecureSkipVerify:這個(gè)標(biāo)志的使用確實(shí)存在安全隱患,但在這個(gè)檢測(cè)場(chǎng)景下是必需的,因?yàn)樗试S你檢查那些已經(jīng)過期、自簽名或由不受信任的 CA 簽發(fā)的證書,這正是我們要檢測(cè)的。核心是,我們只讀取證書的元數(shù)據(jù),而不是依賴它對(duì)服務(wù)器的身份進(jìn)行認(rèn)證。
  • 處理連接錯(cuò)誤:在實(shí)踐中,網(wǎng)絡(luò)問題(如 DNS 解析失敗、連接超時(shí))很常見。上述代碼中已經(jīng)加入了超時(shí)和錯(cuò)誤處理,你應(yīng)該在實(shí)際應(yīng)用中根據(jù)需求區(qū)分這些錯(cuò)誤和證書過期的錯(cuò)誤。
  • 并發(fā)檢查:如果你需要檢查大量域名,建議使用 Go 的 goroutine 并發(fā)執(zhí)行,但要注意控制并發(fā)數(shù)量,以免對(duì)網(wǎng)絡(luò)或目標(biāo)服務(wù)器造成過大壓力。
  • 時(shí)區(qū)處理NotAfter 是 UTC 時(shí)間,而 time.Now() 返回本地時(shí)間。Go 的 time 包在計(jì)算 time.Until 時(shí)會(huì)自動(dòng)處理時(shí)區(qū)差異,所以直接相減是安全的。

方法二:使用GO語言驗(yàn)證證書的有效期

要使用 Go 語言驗(yàn)證證書的有效期,可以使用以下代碼示例:

package main
import (
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "time"
)
func main() {
    certPEM, err := ioutil.ReadFile("path/to/certificate.pem")
    if err != nil {
        fmt.Println("Error reading certificate file:", err)
        return
    }
    block, _ := pem.Decode(certPEM)
    if block == nil {
        fmt.Println("Failed to parse certificate PEM")
        return
    }
    cert, err := x509.ParseCertificate(block.Bytes)
    if err != nil {
        fmt.Println("Error parsing certificate:", err)
        return
    }
    fmt.Println("Certificate Expiry Date:", cert.NotAfter)
    now := time.Now()
    if now.Before(cert.NotBefore) {
        fmt.Println("Certificate is not yet valid")
    } else if now.After(cert.NotAfter) {
        fmt.Println("Certificate has expired")
    } else {
        fmt.Println("Certificate is valid")
    }
}

在上面的代碼中,需要將 path/to/certificate.pem 替換為您要驗(yàn)證的證書文件的路徑。代碼將讀取證書文件,解析證書并檢查當(dāng)前時(shí)間是否在證書的有效期內(nèi)。根據(jù)驗(yàn)證結(jié)果,將輸出相應(yīng)的結(jié)果。

方法三:golang獲取證書過期時(shí)間

func GetDomainSslExpireDate(domain string) string {
	if !strings.HasPrefix(domain, "http") {
		domain = fmt.Sprint("https://", domain)
	}
	command := fmt.Sprint("curl -v -I -k ", domain)
	cmd := exec.Command("/bin/bash", "-c", command)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return time.Time{}
	}
	outStr := string(output)
	outArr := strings.Split(outStr, "\n")
	for _, out := range outArr {
		if strings.Contains(out, "expire date") {
			return out[strings.Index(out, ":")+1:]
			return StrToDate(dateStr)
		}
	}
	return ""
}

到此這篇關(guān)于Golang實(shí)現(xiàn)檢測(cè)SSL證書有效期的文章就介紹到這了,更多相關(guān)Go檢測(cè)https證書有效期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go 語言中的 http.FileSystem詳細(xì)解析

    Go 語言中的 http.FileSystem詳細(xì)解析

    在本文中,我們深入探討了 Go 語言中的 http.FileSystem 接口,并介紹了它的基本原理、使用方法以及實(shí)際應(yīng)用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Go Gin框架中的binding驗(yàn)證器使用小結(jié)

    Go Gin框架中的binding驗(yàn)證器使用小結(jié)

    Gin框架中的binding驗(yàn)證器為我們提供了簡(jiǎn)便的數(shù)據(jù)綁定和驗(yàn)證功能,通過合理使用binding和validate標(biāo)簽,我們可以確保API接口的數(shù)據(jù)合法性和完整性,這篇文章主要介紹了Go Gin框架中的binding驗(yàn)證器使用指南,需要的朋友可以參考下
    2024-07-07
  • go語言版的ip2long函數(shù)實(shí)例

    go語言版的ip2long函數(shù)實(shí)例

    這篇文章主要介紹了go語言版的ip2long函數(shù),實(shí)例分析了Go語言實(shí)現(xiàn)的ip2long函數(shù)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • 一文帶大家搞懂Go語言中的迭代器

    一文帶大家搞懂Go語言中的迭代器

    迭代器是使用戶可在容器對(duì)象上遍訪的對(duì)象,設(shè)計(jì)人員使用此接口無需關(guān)心容器對(duì)象的內(nèi)存分配的實(shí)現(xiàn)細(xì)節(jié),本文主要為大家詳細(xì)介紹一下Go語言中的迭代器的實(shí)現(xiàn),需要的可以了解下
    2025-02-02
  • 淺談golang package中init方法的多處定義及運(yùn)行順序問題

    淺談golang package中init方法的多處定義及運(yùn)行順序問題

    這篇文章主要介紹了淺談golang package中init方法的多處定義及運(yùn)行順序問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go異常處理、泛型和文件操作實(shí)例代碼

    Go異常處理、泛型和文件操作實(shí)例代碼

    Go語言的異常處理機(jī)制與傳統(tǒng)的面向?qū)ο笳Z言(如 Java、C#)所使用的 try-catch 結(jié)構(gòu)有所不同,它采用了自己獨(dú)特的設(shè)計(jì)理念和方法,這篇文章主要介紹了Go異常處理、泛型和文件操作的相關(guān)資料,需要的朋友可以參考下
    2025-12-12
  • golang中的空接口使用詳解

    golang中的空接口使用詳解

    這篇文章主要介紹了golang中的空接口使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang實(shí)現(xiàn)并發(fā)控制的方法和技巧

    golang實(shí)現(xiàn)并發(fā)控制的方法和技巧

    golang 是一門支持并發(fā)的編程語言,它提供了 goroutine 和 channel 等強(qiáng)大的特性,讓我們可以輕松地創(chuàng)建和管理多個(gè)執(zhí)行單元,實(shí)現(xiàn)高效的任務(wù)處理,在本文中,我們將介紹一些 golang 的并發(fā)控制的方法和技巧,希望對(duì)你有所幫助
    2024-03-03
  • 一文帶你掌握GoLang中的指針

    一文帶你掌握GoLang中的指針

    針是?Go?編程語言的重要組成部分,它們提供了一種直接引用和操作內(nèi)存中數(shù)據(jù)的方法,在這篇文章中,我們將探討一些技巧和技巧,以掌握?GoLang?中的指針并編寫高效的代碼,需要的可以參考一下
    2023-05-05

最新評(píng)論

崇明县| 武宣县| 襄樊市| 西藏| 宜丰县| 长寿区| 门源| 花莲县| 容城县| 屏东市| 瑞金市| 阳江市| 淮滨县| 江城| 蒙阴县| 乌鲁木齐市| 万盛区| 永善县| 龙州县| 方正县| 平安县| 娄底市| 莱西市| 金寨县| 大安市| 新源县| 东方市| 兰西县| 尚志市| 台湾省| 石城县| 盐亭县| 盱眙县| 永平县| 桐乡市| 莫力| 延吉市| 区。| 中阳县| 巨野县| 新源县|