學習go語言編程之安全編程

數據加密

對稱加密

採用單密鑰的加密算法,稱爲對稱加密。
常見的單密鑰加密算法有DESAESRC4等。
在對稱加密中,私鑰不能暴露,否則在算法公開的情況下,數據等同於明文。

非對稱加密

採用雙密鑰的加密算法,稱爲非對稱加密。
在該系統中,私鑰和公鑰都可以被用作加密或者解密,但是用私鑰加密的明文,必須要用對應的公鑰解密;用公鑰加密的明文,必須用對應的私鑰解密。
常見的雙密鑰加密算法有RSA等。
在非對稱加密中,公鑰是公開的,私鑰是保密的。這樣任何人都可以把自己的信息通過公鑰和算法加密,然後發送給公鑰的發佈方,只有公鑰發佈方(公鑰發佈方擁有私鑰)才能解開密文。

哈希加密

使用哈希算法可以實現加密後不可解密的需求。
哈希算法是一種從任意數據中創建固定長度摘要信息的辦法,對於不同的數據,要求產生的摘要信息也是唯一的。
常見的哈希算法包括MD5SHA-1等。

數字簽名

數字簽名,是指用於標記數字文件擁有者、創造者、分發者身份的字符串。
常用的數字簽名採用了非對稱加密。
例如,A公司發佈了一個可執行文件,稱爲AProduct.exe,A在AProduct.exe中加入了A公司的數字簽名。A公司的數字簽名是用A公司的私鑰加密了AProduct.exe文件的哈希值,我們得到打過數字簽名的AProduct.exe後,可以查看數字簽名。這個過程實際上是用A公司的公鑰解密了文件哈希值,從而可以驗證兩個問題:AProduct.exe是否由A公司發佈,AProduct.exe是否被篡改。

數字證書

通過數字證書可以實現非對稱加密。
首次使用U盾的時候,初始化過程即是向U盾中下載數字證書。數字證書中包含了銀行的公鑰,有了公鑰之後,網銀就可以用公鑰加密我們提供給銀行的信息,這樣只有銀行才能用對應的私鑰得到我們的信息,確保安全。

PKI體系

PKI,全稱:公鑰基礎設施。
是使用非對稱加密理論,提供數字簽名、加密、數字證書等服務的體系,一般包括權威認證機構(CA)、數字證書庫、密鑰備份及恢復系統、證書作廢系統、應用接口(API)等。

Golang的哈希函數

Go提供了MD5SHA-1等幾種哈希函數,如下示例。

// 對字符串計算哈希值
TestString := "Hello, World!"

// 使用MD5哈希
md5Hash := md5.New()
md5Hash.Write([]byte(TestString))
result := md5Hash.Sum([]byte(""))
fmt.Printf("%x\n", result) // 輸出:65a8e27d8879283831b664bd8b7f0ad4

// 使用SHA-1哈希
sha1Hash := sha1.New()
sha1Hash.Write([]byte(TestString))
result = sha1Hash.Sum([]byte(""))
fmt.Printf("%x\n", result) // 輸出:0a0a9f2a6772942557ab5355d76af442f8f65e01
// 對文件內容計算哈希值
TestFile := "123.txt" // 文件內容:Hello, World!
f, err := os.Open(TestFile)
if err != nil {
    fmt.Println("Open file failed: ", err)
    return
}

// 計算MD5哈希
md5Hash := md5.New()
io.Copy(md5Hash, f)
result := md5Hash.Sum([]byte(""))
fmt.Printf("%x\n", result) // 輸出:65a8e27d8879283831b664bd8b7f0ad4

// 計算SHA-1哈希
sha1Hash := sha1.New()
io.Copy(sha1Hash, f)
result = sha1Hash.Sum([]byte(""))
fmt.Printf("%x\n", result) // 輸出:da39a3ee5e6b4b0d3255bfef95601890afd80709

加密通信

一般的HTTPS是基於SSL(Secure Sockets Layer)協議實現加密通信。

加密通信流程

如下流程是SSL/TLS的工作方式:
(1) 在瀏覽器中輸入HTTPS協議的網址
(2) 服務器向瀏覽器返回證書
(3) 瀏覽器驗證證書合法性
(4) 瀏覽器使用證書中的公鑰加密一個隨機對稱密鑰,並將加密後的密鑰和使用密鑰加密後的請求URL一起發送到服務器
(5) 服務器用私鑰解密隨機對稱密鑰,並用獲取的密鑰解密加密的請求URL
(6) 服務器把用戶請求的網頁用密鑰加密,並返回給用戶
(7) 用戶瀏覽器用密鑰解密服務器發來的網頁數據,並將其顯示出來

總結起來就是:瀏覽器與服務器之間通過非對稱加密的方式交換對稱加密密鑰,數據內容使用對稱加密算法加密後傳輸。

支持HTTPS的Web服務器

const content = "Hello,World!"

func rootHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	w.Header().Set("Content-Length", fmt.Sprint(len(content)))
	w.Write([]byte(content))
}

func main() {
	fmt.Println("支持https的Web服務器")
	http.HandleFunc("/", rootHandler)
	http.ListenAndServeTLS(":8080", "chench.crt", "chench.key", nil) // chench.crt和chench.key分別是自簽名的證書和KEY文件
}

啓動之後在瀏覽器中需要以HTTPS協議來訪問:https://localhost:8080/

支持HTTPS的文件服務器

func main() {
	fmt.Println("支持HTTPS的文件服務器")
	h := http.FileServer(http.Dir("."))
	http.ListenAndServeTLS(":8001", "chench.crt", "chench.key", h) // chench.crt和chench.key分別是自簽名的證書和KEY文件
}

啓動之後以HTTPS協議訪問:https://localhost:8001/

需要注意的是,SSL/TLS協議只能運行於TCP之上,不能在UDP上工作,且SSL/TLS位於TCP與應用層協議之間,因此所有基於TCP的應用層協議都可以透明地使用SSL/TLS爲自己提供安全保障。
所謂透明地使用是指既不需要了解細節,也不需要專門處理該層的包,比如封裝、解封等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章