» Go语言快速入门 » 2. 进阶篇 » 2.1 加密解密

加密解密

crypto 包提供了一系列的密码学基元和算法。

哈希函数

crypto 包提供了一个通用的 hash 包,定义了 hash.Hash 接口。 crypto/sha256crypto/sha512 等子包实现了特定的哈希函数。

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
)

func calculateSHA256(input string) string {
	hasher := sha256.New()
	hasher.Write([]byte(input))
	hash := hasher.Sum(nil)
	return hex.EncodeToString(hash)
}

func main() {
	data := "Hello, Crypto!"
	hash := calculateSHA256(data)
	fmt.Printf("Input: %s\nSHA-256 Hash: %s\n", data, hash)
    // => Input: Hello, Crypto!
    // SHA-256 Hash: de0640f1dc17ca1b01fb9eba3019ed07c12e2af4ae990ecb36aa669898a9fd40
}

对称加密

cipher 包包含了块密码模式(例如 AES、DES)的接口和实现。

package main

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

func encryptAESGCM(key, plaintext string) (string, error) {
	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return "", err
	}

	nonce := make([]byte, 12)
	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
		return "", err
	}

	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", err
	}

	ciphertext := aesgcm.Seal(nil, nonce, []byte(plaintext), nil)
	return hex.EncodeToString(ciphertext), nil
}

func main() {
	key := "0123456789abcdef0123456789abcdef" // AES-256 需要 32 字节
	plaintext := "Hello, AES-GCM!"

	ciphertext, err := encryptAESGCM(key, plaintext)
	if err != nil {
		fmt.Println("Encryption error:", err)
		return
	}

	fmt.Printf("Plaintext: %s\nCiphertext: %s\n", plaintext, ciphertext)
    // => Plaintext: Hello, AES-GCM!
    // => Ciphertext: 9ce45e9cdc452a3e70169bbacf6a926c012462ca0efb5e3945a2a85c539ba3
}

非对称加密

rsa 包支持 RSA 加密和解密。 ecdsa 包支持椭圆曲线数字签名算法。

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"fmt"
)

func encryptRSA(publicKey *rsa.PublicKey, plaintext string) (string, error) {
	ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(plaintext))
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func main() {
	// 在实际应用中,应从文件或其他非硬编码来源加载公钥。
	publicKeyPEM := `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2aWbY8+0wQbOMxvDLgs
+3Cb9SMoyA/2v9MqZrwh4jG28x20aHz/Wng+6vYpFsmw6KrN6k7PZuBn8j/tgyzR
PQFQyXct0p56UM5o6j2gsa1EGZQMHFGiZ0bgqzsc4LCM0Jhz6Dc/0q1q62gjVGUF
oZxq1/2Rrg5n4z5mDPnWozDmupzrMtD9UgA2yV2+u6z2fnUGDT3FJoEZSYwcl4Co
9j8aVj0hl/jhVKuYJ13lh9EDVHdwqojyDWX5U5P+LrDlAlSvs88kH3tlr5S/0sRk
WtRc5d2g+VC/rI3ufkr/YMl9QcNQupXNqA3hq8fVezwwUcd6H62wUsyLOyrUkWmE
BQIDAQAB
-----END PUBLIC KEY-----
`

	block, _ := pem.Decode([]byte(publicKeyPEM))
	if block == nil {
		fmt.Println("Error decoding public key")
		return
	}

	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		fmt.Println("Error parsing public key:", err)
		return
	}

	plaintext := "Hello, RSA!"
	ciphertext, err := encryptRSA(publicKey.(*rsa.PublicKey), plaintext)
	if err != nil {
		fmt.Println("Encryption error:", err)
		return
	}

	fmt.Printf("Plaintext: %s\nCiphertext: %s\n", plaintext, ciphertext)
    // => Plaintext: Hello, RSA!
    // => Ciphertext: X4UG+f0jXTyC+iOy6SPlHeML90her5HOyOz00Yh1XMcYU07B3U6oraEvLySQzQuBAWm8PTkVjZvHaJ1Z9EKRko3kovpIUNGqv6OEwqzc+FMJBHwAfyG7Z9oyKJeNaACaWyCL7bhI4q1TrbrwwzRcUigkX5IHZq3Pz3Zb4dhTv7d50nBKrK4/3Fjxofp5wuyOQrDeYdggV5rkXAJJ+XeYihkbSDjc9xR7ul1b7cxPz9hcfgdvWe+UV5kvuf5TWFpaTxEKMjXxknkYK9T/dgs8w6y29llu/195nSjyumDEovi+AGS32e7id8YmC4JiE4rTvmIWSiLu7QvyAEne4fn4dw==
}

随机数生成

rand 包提供了一种安全的随机数源。

package main

import (
	"crypto/rand"
	"fmt"
	"math/big"
)

func generateRandomString(length int) (string, error) {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	charsetLength := big.NewInt(int64(len(charset)))
	result := make([]byte, length)

	for i := range result {
		randomIndex, err := rand.Int(rand.Reader, charsetLength)
		if err != nil {
			return "", err
		}
		result[i] = charset[randomIndex.Int64()]
	}

	return string(result), nil
}

func main() {
	randomString, err := generateRandomString(16)
	if err != nil {
		fmt.Println("Error generating random string:", err)
		return
	}

	fmt.Println("Random String:", randomString)
    // => Random String: aPL0YL2RuLoqvF9J
}

代码挑战

在 Go 中实现一个使用 SHA-256 的安全的密码哈希工具。

Loading...
> 此处输出代码运行结果
上页
下页