我试图在存储敏感数据之前对其进行加密。首先,我生成一个用于加密过程的密钥:
import (
"crypto/aes"
CR "crypto/rand"
"encoding/hex"
"errors"
"log"
"os"
)
// []byte key used to encrypt tokens before saving to local file system
var key = make([]byte, 32)
func createKey(key *[]byte) {
_, err = CR.Read(*key)
if err != nil {
log.Println("Error creating key from crypto/rand package:", err)
}
}接下来,我创建了分别加密和解密字符串的函数:
func encryptToken(t token) string {
original := t.ID // ID is string member of token
cipher, err := aes.NewCipher(key)
if err != nil {
log.Println("Error creating cipher during encrypt:", err)
}
out := make([]byte, len(original))
cipher.Encrypt(out, []byte(original))
return hex.EncodeToString(out) // this will be written to a csv file
// appears in file as: cec35df876e1b77diefg9023366c5f2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
}
func decryptToken(s string) string {
ciphertext, err := hex.DecodeString(s) // s is read from csv file
if err != nil {
log.Println("Error decoding string from hex:", err)
}
cipher, err := aes.NewCipher(key)
if err != nil {
log.Println("Error creating cipher during decrypt:", err)
}
original := make([]byte, len(ciphertext))
cipher.Decrypt(original, ciphertext)
originalAsString := string(original[:])
return originalAsString // returns: 6f928e728f485403
// original token was: 6f928e728f485403e254049f684ea5ec853adcfa9553cdfc956fr45671447c57
}考虑到encryptToken()返回一个包含如此多零的十六进制字符串,我确信这就是我的问题所在。我已经尝试过调整key的长度,但是在var key = make([]byte, 32)中使用32以外的值将导致出现涉及无效内存地址或零指针取消引用的恐慌。为什么会这样呢?
发布于 2022-11-13 09:02:35
最短的答案可能是:正如@GradyPlayer建议的那样,您使用密码的方式是错误的。您必须将其交给加密器,后者将其应用于所有字节。模式看起来是这样的:
ciphertext = make([]byte, len(plaintext))
cbc := cipher.NewCBCEncrypter(cipher, iv)
cbc.CryptBlocks(ciphertext, plaintext)尽管如此,在这里您仍然需要将初始化向量放在密文前面(至少这是放置它的通常位置,解密器可能希望它位于这里),您仍然需要考虑填充(如果您像我一样使用CBC )。
因此,虽然它没有直接解决这个问题,但我认为它可以帮助您获得更多的代码,以便更好地理解。这里是我刚刚创建的一个要点。免责声明:我主要是从其他地方组装代码片段。所以,我只是把你在这里看到的片段放在一起,在路上获得了一些了解。
发布于 2022-11-13 03:51:45
发布于 2022-11-13 12:34:47
以下按注释编辑(为了正确地使用nonce):
接受的答案,特别是来自Topaco的评论,帮助我找到了这个解决方案,我在这里为任何可能遇到这种情况的人发帖子:
var key = make([]byte, 32)
func encryptToken(t token) string {
original := t.ID // ID is string member of token
var nonce = make([]byte, 12)
// read random bytes into nonce
_, err := rand.Read(nonce)
if err != nil {
log.Println("Error reading random bytes into nonce:", err)
}
block, err := aes.NewCipher(key)
if err != nil {
log.Println("Error creating cipher during encrypt:", err)
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
log.Println("Error creating GCM during encrypt:", err)
}
ciphertext := aesgcm.Seal(nil, nonce, []byte(original), nil)
// prepend the ciphertext with the nonce
out := append(nonce, ciphertext...)
return hex.EncodeToString(out)
}
func decryptToken(s string) string {
// read hex string describing nonce and ciphertext
enc, err := hex.DecodeString(s)
if err != nil {
log.Println("Error decoding string from hex:", err)
}
// separate ciphertext from nonce
nonce := enc[0:12]
ciphertext := enc[12:]
block, err := aes.NewCipher(key)
if err != nil {
log.Println("Error creating cipher during decrypt:", err)
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
log.Println("Error creating GCM during decrypt:", err)
}
original, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
log.Println("Error decrypting to string:", err)
}
originalAsString := string(original)
return originalAsString
}参考资料:https://pkg.go.dev/crypto/cipher#example-NewGCM-Encrypt
https://stackoverflow.com/questions/74418323
复制相似问题