gpt4 book ai didi

c# - C# 中使用 MD5 和 SHA256 的 CryptoJS AES 加密未生成正确的值

转载 作者:行者123 更新时间:2023-12-04 07:54:10 30 4
gpt4 key购买 nike

我想在 CryptoJS 和 C# 中使用加密密码。不幸的是,我的 C# 代码无法生成正确的值。这是我的代码

internal static byte[] ComputeSha256(this byte[] value)
{
using (SHA256 sha256Hash = SHA256.Create())
return sha256Hash.ComputeHash(value);
}

internal static byte[] ComputeSha256(this string value) => ComputeSha256(Encoding.UTF8.GetBytes(value));

internal static byte[] ComputeMD5(this byte[] value)
{
using (MD5 md5 = MD5.Create())
return md5.ComputeHash(value);
}

internal static byte[] ComputeMD5(this string value) => ComputeMD5(Encoding.UTF8.GetBytes(value));

internal static byte[] CombineByteArray(byte[] first, byte[] second)
{
byte[] bytes = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, bytes, 0, first.Length);
Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length);
return bytes;
}

internal static string EncryptPassword()
{
using (AesManaged aes = new AesManaged())
{
//CLIENT SIDE PASSWORD HASH
/*
var password = '12345';
var passwordMd5 = CryptoJS.MD5(password);
var passwordKey = CryptoJS.SHA256(CryptoJS.SHA256(passwordMd5 + '12345678') + '01234567890123456');
var encryptedPassword = CryptoJS.AES.encrypt(passwordMd5, passwordKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding });
encryptedPassword = CryptoJS.enc.Base64.parse(encryptedPassword.toString()).toString(CryptoJS.enc.Hex);
//encryptedPassword result is c3de82e9e8a28a4caded8c2ef0d49c80
*/

var y1 = Encoding.UTF8.GetBytes("12345678");
var y2 = Encoding.UTF8.GetBytes("01234567890123456");
var password = "12345";
var passwordMd5 = ComputeMD5(password);

var xkey = CombineByteArray(ComputeSha256(CombineByteArray(passwordMd5, y1)), y2);
var passwordKey = ComputeSha256(xkey);

aes.Key = passwordKey;
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
ICryptoTransform crypt = aes.CreateEncryptor();
byte[] cipher = crypt.TransformFinalBlock(passwordMd5, 0, passwordMd5.Length);
var encryptedPassword = BitConverter.ToString(cipher).Replace("-", "").ToLower();
return encryptedPassword; //e969b60e87339625c32f805f17e6f993
}
}

上述 C# 代码的结果是 e969b60e87339625c32f805f17e6f993。它应该与 CryptoJS c3de82e9e8a28a4caded8c2ef0d49c80 相同。这里有什么问题?

最佳答案

在 CryptoJS 代码哈希(以 WordArray 的形式)和字符串被添加到几个地方。因此,WordArray 使用 toString() 隐式编码为小写字母的十六进制字符串。 C# 代码中缺少这一点。

在 C# 代码中,添加是通过 CombineByteArray() 完成的,其中散列作为 byte[] 在参数 first 中传递.因此这个参数必须先转换为小写字母的十六进制编码字符串,然后再进行UTF8编码,例如:

internal static byte[] CombineByteArray(byte[] first, byte[] second)
{
// Hex encode (with lowercase letters) and Utf8 encode
string hex = ByteArrayToString(first).ToLower();
first = Encoding.UTF8.GetBytes(hex);

byte[] bytes = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, bytes, 0, first.Length);
Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length);
return bytes;
}

其中 ByteArrayToString() 来自 here .

通过此更改,C# 代码给出与 CryptoJS 代码相同的结果。


我不太清楚 CryptoJS 代码的用途。通常明文和 key 是独立的,即不是从同一个密码派生的。
也许这应该实现自定义的基于密码的 key 派生功能。如果是这样,并且除非出于兼容性原因强制执行自定义实现,否则使用经过验证的算法(例如 Argon2 或 PBKDF2)会更安全。特别是,缺少盐/工作因素是不安全的。

关于c# - C# 中使用 MD5 和 SHA256 的 CryptoJS AES 加密未生成正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66794892/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com