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 使用