Go (Golang) 中的密码学:加密与哈希

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Go (Golang) 中的密码学:加密与哈希完全指南



Go (Golang) 提供了强大的标准库 crypto,其中包含了实现数据加密保护所需的所有工具。在本文中,我们将详细讲解 Go 中加密和哈希的主要功能,包括对称加密 (AES)、非对称加密 (RSA)、哈希函数 (SHA-256) 以及使用 bcrypt 进行密码保护。



1. Go 中的数据哈希



哈希是一种将数据转换为固定长度值的单向过程。在 Go 中,这通过 crypto/sha256 包(以及其他 SHA 系列)实现。



示例:字符串的 SHA-256 哈希



package main

import ( "crypto/sha256" "fmt")

func main() { data := "PythonLib.ru — 教育网站" hash := sha256.Sum256([]byte(data)) fmt.Printf("SHA-256: %x", hash)}


输出: SHA-256: 3c4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4



对于流式哈希(大文件),请使用 hash.Hash 接口:



package main

import ( "crypto/sha256" "fmt" "io" "strings")

func main() { h := sha256.New() reader := strings.NewReader("用于哈希的数据流") io.Copy(h, reader) fmt.Printf("流式 SHA-256: %x", h.Sum(nil))}


2. 使用 bcrypt 保护密码



存储密码时,切勿使用普通哈希(如 SHA-256)。请使用 bcrypt——一种带盐值和自适应复杂度的算法。在 Go 中,这由 golang.org/x/crypto/bcrypt 包实现。



安装:

go get golang.org/x/crypto/bcrypt


密码哈希与验证示例:



package main

import ( "fmt" "golang.org/x/crypto/bcrypt")

func main() { password := "MySecurePass123!"

// 哈希(默认成本 = 10) hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { panic(err) } fmt.Printf("bcrypt hash: %s", hash)

// 验证密码 err = bcrypt.CompareHashAndPassword(hash, []byte(password)) if err != nil { fmt.Println("密码错误") } else { fmt.Println("密码正确!") }}


3. 对称加密 AES-GCM



AES(高级加密标准)是一种对称算法。推荐使用 GCM(伽罗瓦/计数器模式),它提供认证加密(AEAD)。请使用 crypto/aes 和 crypto/cipher 包。



AES-256-GCM 加密与解密示例:



package main

import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io")

func main() { key := []byte("32-字节密钥用于AES-256!!!") // 32 字节 plaintext := []byte("给 PythonLib 的秘密消息")

// 加密 ciphertext, nonce := encryptAESGCM(key, plaintext) fmt.Printf("已加密: %s", hex.EncodeToString(ciphertext))

// 解密 decrypted, err := decryptAESGCM(key, ciphertext, nonce) if err != nil { panic(err) } fmt.Printf("已解密: %s", decrypted)}

func encryptAESGCM(key, plaintext []byte) (ciphertext, nonce []byte) { block, _ := aes.NewCipher(key) gcm, _ := cipher.NewGCM(block) nonce = make([]byte, gcm.NonceSize()) io.ReadFull(rand.Reader, nonce) return gcm.Seal(nil, nonce, plaintext, nil), nonce}

func decryptAESGCM(key, ciphertext, nonce []byte) ([]byte, error) { block, _ := aes.NewCipher(key) gcm, _ := cipher.NewGCM(block) return gcm.Open(nil, nonce, ciphertext, nil)}


4. 非对称加密 RSA



RSA 使用

推荐