【发布时间】:2021-02-16 09:01:31
【问题描述】:
我正在我的 Go 应用程序中寻找加密字符串并使用 Crypto-js 解密编码的字符串。
我已经尝试了几个小时但没有成功,尝试了 Stackoverflow、github 或 gist 提供的许多解决方案。
如果有人有解决方案,他们会让我免于某种神经衰弱,哈哈
我的 Go 加密代码:
func EncryptBody() (encodedmess string, err error) {
key := []byte("6368616e676520746869732070617373")
// Create the AES cipher
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
plaintext, _ := pkcs7Pad([]byte("exampletext"), block.BlockSize())
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
bm := cipher.NewCBCEncrypter(block, iv)
bm.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
return fmt.Sprintf("%x", ciphertext), nil
}
我的 pkcs7Pad 功能:
func pkcs7Pad(b []byte, blocksize int) ([]byte, error) {
if blocksize <= 0 {
return nil, errors.New("invalid blocksize")
}
if b == nil || len(b) == 0 {
return nil, errors.New("invalid PKCS7 data (empty or not padded)")
}
n := blocksize - (len(b) % blocksize)
pb := make([]byte, len(b)+n)
copy(pb, b)
copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))
return pb, nil
}
我的 Crypto-JS 解密代码:
public decryptData() {
const data = "3633fbef042b01da5fc4b69d8f038a83130994a898137bb0386604cf2c1cbbe6"
const key = "6368616e676520746869732070617373"
const decrypted = CryptoJS.AES.decrypt(data, key, {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
console.log("Result : " + decrypted.toString(CryptoJS.enc.Hex))
return decrypted.toString(CryptoJS.enc.Hex)
}
【问题讨论】:
-
为了解密,你剥离 IV 并将其用作解密的输入,但随后你将 complete 数据提供给“CryptoJS.AES.decrypt(data, key”) - 恕我直言,输入应该是剩余的数据(在切断 IV 之后)。由于我不是 Go 专家,加密看起来很奇怪 - 你是在结合 CBC 模式加密和 CFB 模式加密吗?如果是这样的话您还需要在 cryptojs 端扭转这一点。
-
两种代码在功能上非常不同。在 CryptoJS 代码中,密钥作为字符串传递,这就是应用密钥派生函数的原因。为避免这种情况,必须使用 Utf8 编码器解析密钥。在 CryptoJS 代码中,由于是十六进制编码,IV 必须使用 32 个字符。此外,密文必须在没有 IV 的情况下传递给
CryptoJS.AES.decrypt()(迈克尔费尔的评论),并且还必须作为 CipherParams` 对象(或 Base64 编码)。 -
在Go代码中,先进行了一次CBC加密,但是结果被后面的CFB加密覆盖了。 CFB 作为流密码模式不需要填充,但两种代码都使用填充。顺便说一句,CFB 并非不重要,因为库通常不会默认使用相同的段大小。在这里你很幸运,在这两种情况下都应用了 CFB128。
-
您好,感谢您的回复。我已经用你的建议更新了我的代码,但没有结果。您能对我的新版本发表意见吗?
-
感谢@Topaco 的帮助!
标签: go encryption cryptography aes cryptojs