【发布时间】:2013-09-19 23:20:21
【问题描述】:
我正在尝试加密数据库中的一些文本,以便在程序启动期间加载和解密。
我尝试了几种方法,包括第三方库https://github.com/richard-lyman/lithcrypt 均无济于事。使用以下方法加密/解密 8/10 项,但似乎在加密/解密中的某个点留下了一些填充残留物。就目前而言,我的代码是这样的:
package client
import (
"encoding/base64"
"crypto/aes"
"crypto/cipher"
"fmt"
)
var iv = []byte{34, 35, 35, 57, 68, 4, 35, 36, 7, 8, 35, 23, 35, 86, 35, 23}
func encodeBase64(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}
func decodeBase64(s string) []byte {
data, err := base64.StdEncoding.DecodeString(s)
if err != nil { panic(err) }
return data
}
func Encrypt(key, text string) string {
block, err := aes.NewCipher([]byte(key))
if err != nil { panic(err) }
plaintext := []byte(text)
cfb := cipher.NewCFBEncrypter(block, iv)
ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext)
return encodeBase64(ciphertext)
}
func Decrypt(key, text string) string {
block, err := aes.NewCipher([]byte(key))
if err != nil { panic(err) }
ciphertext := decodeBase64(text)
cfb := cipher.NewCFBEncrypter(block, iv)
plaintext := make([]byte, len(ciphertext))
cfb.XORKeyStream(plaintext, ciphertext)
}
有人提到我可能需要填充字符串,但我必须填充流密码似乎很奇怪。
下面是这个错误的一个例子:http://play.golang.org/p/4FQBAeHgRs
【问题讨论】:
-
不确定这是否有帮助,但在您发布的操场示例中,超过 16 字节字符串的任何内容都会出现错误。将密钥设置为 32 字节字符串(而不是 24 字节)可以成功解码您的“plaintext1”字符串。
-
我希望 IV 是一个常数,仅用于说明目的。 IV 代表初始化向量,这对于每个加密应该是随机的,并且应该保存在密文中。解密时,首先从密文中提取 IV,然后进行通常的解密。来自 Wikipedia (en.wikipedia.org/wiki/…):对于 CBC 和 CFB,重用 IV 会泄露一些关于第一个明文块以及两条消息共享的任何公共前缀的信息。
-
@Kluyg 非常好的观点。我已修改我的答案以使用推荐的 IV 创建方法。
-
免责声明:我不是安全专家。 但我开发了这个库,可能会对您有所帮助 github.com/phylake/go-crypto,我强烈推荐 Cryptography Engineering: Design Principles and Practical Applications,它提供了很多清晰性各种流和分组密码模式。
标签: encryption go base64 aes