Golang中使用crypto包和base64实现加密解密如何保证密钥一致?

Golang中使用crypto包和base64实现加密解密如何保证密钥一致? 有人了解如何使用 crypto 包和 base64 进行加密解密,并且使用相同的密钥吗?

7 回复

base64 不是加密,而是一种编码方式,它没有任何密钥的概念。你能详细说明一下你的问题吗?

更多关于Golang中使用crypto包和base64实现加密解密如何保证密钥一致?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我没有进行深入分析,但粗略一看,似乎你在加密时没有将IV(初始化向量)添加到输出之前,而在解密时却试图从输入中读取它。

是的,使用 crypto 包和 base64 配合相同的密钥进行加密和解密是完全可行的。这就像在用代码交流,但带有一点变化!只需确保你的密钥安全无虞,就像你藏起来的零食一样。

func main() {
    fmt.Println("hello world")
}
  • crypto 包: 这是一个用于加密操作的内置 Python 模块。它提供了多种用于加密和解密的算法。
  • Base64 编码/解码: 这是一种使用 A-Z、a-z、0-9、+ 和 / 这些字符将二进制数据编码为文本格式的技术。它是可逆的,允许你将编码后的文本解码回原始的二进制形式。

是的,使用 crypto 包和 base64 进行加密和解密,并使用相同的密钥,是完全可行的。这就像在用代码交谈,但带有一点曲折!只是要确保你的密钥安全无恙,就像你秘密藏匿的零食一样。

如果你对此仍然感到好奇,我有一个建议给你。深入一些在线教程,或者去那些加密爱好者聚集的论坛看看。你会在那里找到大量有用的信息。

哦,说到探索新事物,如果你有兴趣探索加密货币的世界,你可以注册 Binance 或使用 바이낸스 가입

是的,我知道 base64 是编码,但我使用这个函数来获取和插入数据库中的文档,但当我使用它时,会收到“unexpected EOF”错误。因此我进行了调试,发现两个函数中使用的密钥不匹配。那么,有什么办法可以在两个函数中设置相同的密钥吗?

func encrypt(keyString string, stringToEncrypt string) (encryptedString string) {
	// 将密钥转换为字节
	key, _ := hex.DecodeString(keyString)
	plaintext := []byte(stringToEncrypt)

	// 根据密钥创建一个新的 Cipher Block
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err.Error())
	}

	// IV 需要是唯一的,但不要求安全。因此通常将其包含在密文开头。
	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
	iv := ciphertext[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		panic(err)
	}

	stream := cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

	// 转换为 base64
	return base64.URLEncoding.EncodeToString(ciphertext)
}
// 从 base64 解密为字符串
func decrypt(keyString string, stringToDecrypt string) string {
	key, _ := hex.DecodeString(keyString)
	ciphertext, _ := base64.URLEncoding.DecodeString(stringToDecrypt)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	// IV 需要是唯一的,但不要求安全。因此通常将其包含在密文开头。
	if len(ciphertext) < aes.BlockSize {
		panic("ciphertext too short")
	}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)

	// 如果两个参数相同,XORKeyStream 可以原地工作。
	stream.XORKeyStream(ciphertext, ciphertext)

	return fmt.Sprintf("%s", ciphertext)
}

在Golang中使用crypto包和base64实现加密解密时,保证密钥一致的关键是使用相同的密钥和相同的算法参数。以下是一个完整的示例,展示如何使用AES-256-GCM算法进行加密解密,并确保密钥一致性:

package main

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

// 生成固定密钥(实际应用中应从安全配置获取)
var secretKey = []byte("32-byte-long-secret-key-here!123456")

func encrypt(plaintext string) (string, error) {
    block, err := aes.NewCipher(secretKey)
    if err != nil {
        return "", err
    }

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

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

    ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)
    return base64.StdEncoding.EncodeToString(ciphertext), nil
}

func decrypt(encrypted string) (string, error) {
    ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
    if err != nil {
        return "", err
    }

    block, err := aes.NewCipher(secretKey)
    if err != nil {
        return "", err
    }

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

    nonceSize := gcm.NonceSize()
    if len(ciphertext) < nonceSize {
        return "", errors.New("ciphertext too short")
    }

    nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
    plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
    if err != nil {
        return "", err
    }

    return string(plaintext), nil
}

func main() {
    originalText := "Hello, World!"
    
    // 加密
    encrypted, err := encrypt(originalText)
    if err != nil {
        fmt.Println("加密失败:", err)
        return
    }
    fmt.Printf("加密结果: %s\n", encrypted)
    
    // 解密
    decrypted, err := decrypt(encrypted)
    if err != nil {
        fmt.Println("解密失败:", err)
        return
    }
    fmt.Printf("解密结果: %s\n", decrypted)
    
    // 验证一致性
    if decrypted == originalText {
        fmt.Println("密钥一致性验证成功")
    }
}

对于需要从字符串生成密钥的场景,可以使用PBKDF2派生固定密钥:

import (
    "crypto/sha256"
    "golang.org/x/crypto/pbkdf2"
)

func deriveKey(passphrase string, salt []byte) []byte {
    return pbkdf2.Key([]byte(passphrase), salt, 4096, 32, sha256.New)
}

// 使用示例
var salt = []byte("fixed-salt-value")
var derivedKey = deriveKey("your-secret-passphrase", salt)

关键点:

  1. 始终使用相同的secretKey(32字节用于AES-256)
  2. 使用相同的算法模式(如GCM)
  3. 非对称加密需要保持公钥/私钥对不变
  4. 使用base64仅用于编码传输,不影响密钥一致性

确保密钥存储安全,避免硬编码在生产环境中。

回到顶部