【发布时间】:2022-01-08 03:19:22
【问题描述】:
我在 node.js 中有以下代码,使用 crypto-js 使用带有密钥和 IV 的 AES 加密密码。
const crypto = require('crypto-js');
const cryptKey = 'b676eac8cf70442385dfd4bcfaa61b52';
const createRandomIv = function () {
const keySize = 192 / 32;
const ivSize = 128 / 32;
const evp = crypto.algo.EvpKDF.create({ keySize: keySize + ivSize, hasher: crypto.algo.SHA1 }).compute(cryptKey);
const iv = crypto.lib.WordArray.create(evp.words.slice(keySize), ivSize * 4);
return iv.toString();
};
const encryptPassword = function (password) {
const iv = createRandomIv();
const hash = crypto.AES.encrypt(
password,
cryptKey, {
iv,
mode: crypto.mode.CTR
}
);
const base64 = crypto.enc.Base64.parse(hash.toString());
const eHex = base64.toString(crypto.enc.Hex);
return `${iv}:${eHex}`;
};
const decryptPassword = function (encryptedPwd) {
const split = encryptedPwd.split(':');
if (split.length < 2) return '';
const reb64 = crypto.enc.Hex.parse(split[1]);
const bytes = reb64.toString(crypto.enc.Base64);
const hash = crypto.AES.decrypt(bytes, cryptKey, {
iv: split[0],
mode: crypto.mode.CTR
});
const plain = hash.toString(crypto.enc.Utf8);
return plain;
};
这是来自节点 js 的加密密码。
const encryptedPassword = encryptPassword("Stack Overflow");
console.log(encryptedPassword);
// 2db5c01b4825b6d4dd7a7b96f04f3bb5:53616c7465645f5f691671363cda1b9d05ee6bdd637e1e99bc3b29ef2ad7ec53
并且已经尝试使用 golang 对其进行解密,如下所示
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"strings"
)
func main() {
secretKey := "b676eac8cf70442385dfd4bcfaa61b52"
encryptedPwd := "2db5c01b4825b6d4dd7a7b96f04f3bb5:53616c7465645f5f691671363cda1b9d05ee6bdd637e1e99bc3b29ef2ad7ec53"
split := strings.Split(encryptedPwd, ":")
c, _ := aes.NewCipher([]byte(secretKey))
cfbdec := cipher.NewCBCDecrypter(c, []byte(split[0]))
plaintext := make([]byte, len(split[1]))
cfbdec.CryptBlocks(plaintext, []byte(split[1]))
fmt.Println(plaintext)
}
但它恐慌如下。
恐慌:cipher.NewCBCDecrypter:IV 长度必须等于块大小 goroutine 1 [运行]: crypto/cipher.NewCBCDecrypter({0x10c4ee8, 0xc000066060}, {0xc00001e040, 0x1, 0x20})
更新 1
我在不使用 iv 的情况下将代码更新为解密,但结果不可读。
split := strings.Split(encryptedPwd, ":")
ciphertext, _ := hex.DecodeString(split[1])
c, _ := aes.NewCipher([]byte(secretKey))
plaintext := make([]byte, len(ciphertext))
c.Decrypt(plaintext, []byte(ciphertext))
fmt.Println(string(plaintext))
|A/��c�*Z�S/�x
我的golang代码中的解密有什么问题,有人可以帮我吗?我已经使用了相同的密钥,并且通过将其从加密密码中拆分出来。
【问题讨论】:
-
如果你登录
encryptPassword()这两个值,iv和hash.iv.toString(),你会发现它们是不同的,即在加密过程中忽略了用createRandomIv()精心确定的IV。 -
@Topaco 什么意思,iv 在冒号前第一段的加密密码中,而且我已经使用相同的密钥和iv,那么如何修复它?
-
我建议你先用 CryptoJS 解密密文。然后你会注意到用
createRandomIv()创建的IV不需要解密。 -
你为什么还要在 Node.js 上使用 CryptoJS? Node.js 有built-in crypto。
-
@Topaco 我用使用 iv 的 nodejs 上的解密函数更新了问题
标签: node.js go encryption aes