Go (Golang) 中的密码学:数据加密与哈希
Go 语言(Golang)为密码学操作提供了强大而优雅的标准库。与许多其他需要安装第三方包的语言不同,Go 直接"开箱即用"地支持对称和非对称加密,以及现代哈希算法。在本文中,我们将详细介绍如何在教育门户网站 pythonlib.ru 上使用 Go 的密码学来保护数据。
Go 中的主要密码学包
Go 中的所有密码学功能都集中在 crypto 包及其子包中。以下是其中的关键包:
crypto/aes— Advanced Encryption Standard (AES) 的实现。crypto/cipher— 加密模式(CBC、GCM、CTR)的接口。crypto/rsa— RSA 非对称加密。crypto/sha256、crypto/sha512— SHA-2 系列的哈希函数。golang.org/x/crypto/bcrypt— 自适应密码哈希(附加包)。crypto/rand— 密码学安全的随机数生成器。
Go 中的 AES 对称加密
对称加密使用相同的密钥进行加密和解密。让我们看一个使用 GCM(Galois/Counter Mode)模式的 AES-256 示例,该模式提供数据认证。
package main
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io")
func encryptAES(plaintext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
// 创建 GCM(Galois/Counter Mode) gcm, err := cipher.NewGCM(block) if err != nil { return nil, err }
// 生成随机 nonce(一次性使用的数字) nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err }
// Seal 将 nonce 添加到密文开头 ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) return ciphertext, nil}
func decryptAES(ciphertext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
gcm, err := cipher.NewGCM(block) if err != nil { return nil, err }
nonceSize := gcm.NonceSize() if len(ciphertext) < nonceSize { return nil, fmt.Errorf("ciphertext too short") }
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, err } return plaintext, nil}
func main() { key := []byte("examplekey123456") // AES-128 需要 16 字节 plaintext := []byte("PythonLib 的机密数据")
encrypted, _ := encryptAES(plaintext, key) fmt.Println("加密后 (hex):", hex.EncodeToString(encrypted))
decrypted, _ := decryptAES(encrypted, key) fmt.Println("解密后:", string(decrypted))}请注意:密钥长度必须为 16、24 或 32 字节,分别对应 AES-128、AES-192 或 AES-256。Nonce (IV) 是随机生成的,并与密文一起保存。
Go 中的 RSA 非对称加密
RSA 使用一对密钥:公钥用于加密,私钥用于解密。这对于服务器和客户端之间的安全数据交换非常理想。
package main
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt")
func generateKeyPair(bits int) (*rsa.PrivateKey, error) {