将JavaScript解密重构为C#-AES 128

将JavaScript解密重构为C#-AES 128,javascript,c#,encryption,aes,pbkdf2,Javascript,C#,Encryption,Aes,Pbkdf2,我需要使用JavaScript对消息进行解密并将其转换为C。我有解密信息(下面的“decrypt”变量),看起来像:AES-128::。下面是JavaScript: function decodeString(message, decrypt) { var parts = decrypt.split(':', 4); var salt = CryptoJS.enc.Hex.parse(parts[1]); var iv = CryptoJS.enc.Hex.parse(p

我需要使用JavaScript对消息进行解密并将其转换为C。我有解密信息(下面的“decrypt”变量),看起来像:
AES-128::
。下面是JavaScript:

function decodeString(message, decrypt) {
    var parts = decrypt.split(':', 4);
    var salt = CryptoJS.enc.Hex.parse(parts[1]);
    var iv = CryptoJS.enc.Hex.parse(parts[2]);
    var key = CryptoJS.PBKDF2(parts[3], salt, { keySize: 128/32, iterations: 100 });
    try {
        message = message.replace(/\s+/g, '');
        var d = CryptoJS.AES.decrypt(message, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
        message = d.toString(CryptoJS.enc.Utf8);
    } catch (e) {
        console.error("Encountered a problem decrypting and encrypted page!");
        console.log(e);
    }
    
    return(message);       
}
这是我在C#中所做的,但是我在CreateDecryptor调用中遇到了一个异常

using System.Security.Cryptography;

private string DecodeString(string message, string decrypt)
{
    string[] parts = decrypt.ToString().Split(':');
    byte[] salt = Encoding.UTF8.GetBytes(parts[1]);
    byte[] iv = Encoding.UTF8.GetBytes(parts[2]);
    var pbkdf2 = new Rfc2898DeriveBytes(parts[3], salt, 100);
    int numKeyBytes = 128;  // Not sure this is correct
    byte[] key = pbkdf2.GetBytes(numKeyBytes);

    string plainText = null;
    using (AesManaged aes = new AesManaged())
    {
        aes.KeySize = numKeyBytes;  // Not sure if this is correct
        aes.BlockSize = 128;    // Defaults to 128, but not sure this is correct
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        try
        {
            // The below line has the following exception:
            //    The specified key is not a valid size for this algorithm.
            //    Parameter name: key
            using (var decrypter = aes.CreateDecryptor(key, iv))
            using (var plainTextStream = new MemoryStream())
            {
                using (var decrypterStream = new CryptoStream(plainTextStream, decrypter, CryptoStreamMode.Write))
                using (var binaryWriter = new BinaryWriter(decrypterStream))
                {
                    string encryptedText = Regex.Replace(message, @"\s+", "");
                    binaryWriter.Write(encryptedText);
                }
                byte[] plainTextBytes = plainTextStream.ToArray();
                plainText = Encoding.UTF8.GetString(plainTextBytes);
            }
        }
        catch (Exception ex)
        {
            log.Error("Unable to decrypt message.", ex);
        }

        return plainText;
    }
}

如有任何建议,将不胜感激

在C#代码中存在以下问题:

  • Salt和IV必须是十六进制解码(而不是UTF8编码)
  • numKeyBytes
    以字节为单位指定密钥大小,因此AES-128的密钥大小为16(而不是128)
  • aes.KeySize
    以位为单位指定密钥大小,因此为
    numKeyBytes*8
    (而不是
    numKeyBytes
    ),但也可以省略
  • 对于
    aes.BlockSize
    aes.Mode
    aes.Padding
    使用默认值(128、CBC、PKCS7),因此不需要明确指定它们
  • encryptedText
    必须是Base64解码
一种可能的实施方式是:

私有字符串解密(字符串消息,字符串解密)
{
string[]parts=decrypt.ToString().Split(“:”);
字节[]salt=StringToByteArray(部分[1]);//十六进制解码salt
字节[]iv=StringToByteArray(部分[2]);//十六进制dedoce iv
var pbkdf2=新的Rfc2898DeriveBytes(第[3]部分,salt,100);
int numKeyBytes=16;//AES-128密钥大小(字节):16
byte[]key=pbkdf2.GetBytes(numKeyBytes);
字符串明文=空;
使用(AesManaged aes=新AesManaged())
{
aes.KeySize=192;
尝试
{
字符串encryptedText=Regex.Replace(消息@“\s+”,“”);
使用(var decrypter=aes.CreateDecryptor(key,iv))
使用(MemoryStream msDecrypt=new MemoryStream(Convert.FromBase64String(encryptedText))//Base64解码密文
{
使用(CryptoStream csDecrypt=新加密流(msDecrypt、解密程序、CryptoStreamMode.Read))
{
使用(StreamReader srDecrypt=新的StreamReader(csDecrypt))
{
明文=srDecrypt.ReadToEnd();
}
}
}
}
捕获(例外情况除外)
{
Console.WriteLine(“无法解密消息。”,ex);
}
返回纯文本;
}
}
其中
StringToByteArray()
来自

我将流部分更改为类似,但原始实现也可以工作,因此此更改是可选的

测试:两个代码都返回数据

message=“yhyxejnanruuonwvzlha59trowkeewtkotskoicrd/iBKkGgIp+dewmvexhau53”;
decrypt=“AES-128:303132333435363733839303132333435:35343332313039383736353433323130:我的密码短语”;
明文规定:

敏捷的棕色狐狸跳过了懒狗 在C代码中存在以下问题:

  • Salt和IV必须是十六进制解码(而不是UTF8编码)
  • numKeyBytes
    以字节为单位指定密钥大小,因此AES-128的密钥大小为16(而不是128)
  • aes.KeySize
    以位为单位指定密钥大小,因此为
    numKeyBytes*8
    (而不是
    numKeyBytes
    ),但也可以省略
  • 对于
    aes.BlockSize
    aes.Mode
    aes.Padding
    使用默认值(128、CBC、PKCS7),因此不需要明确指定它们
  • encryptedText
    必须是Base64解码
一种可能的实施方式是:

私有字符串解密(字符串消息,字符串解密)
{
string[]parts=decrypt.ToString().Split(“:”);
字节[]salt=StringToByteArray(部分[1]);//十六进制解码salt
字节[]iv=StringToByteArray(部分[2]);//十六进制dedoce iv
var pbkdf2=新的Rfc2898DeriveBytes(第[3]部分,salt,100);
int numKeyBytes=16;//AES-128密钥大小(字节):16
byte[]key=pbkdf2.GetBytes(numKeyBytes);
字符串明文=空;
使用(AesManaged aes=新AesManaged())
{
aes.KeySize=192;
尝试
{
字符串encryptedText=Regex.Replace(消息@“\s+”,“”);
使用(var decrypter=aes.CreateDecryptor(key,iv))
使用(MemoryStream msDecrypt=new MemoryStream(Convert.FromBase64String(encryptedText))//Base64解码密文
{
使用(CryptoStream csDecrypt=新加密流(msDecrypt、解密程序、CryptoStreamMode.Read))
{
使用(StreamReader srDecrypt=新的StreamReader(csDecrypt))
{
明文=srDecrypt.ReadToEnd();
}
}
}
}
捕获(例外情况除外)
{
Console.WriteLine(“无法解密消息。”,ex);
}
返回纯文本;
}
}
其中
StringToByteArray()
来自

我将流部分更改为类似,但原始实现也可以工作,因此此更改是可选的

测试:两个代码都返回数据

message=“yhyxejnanruuonwvzlha59trowkeewtkotskoicrd/iBKkGgIp+dewmvexhau53”;
decrypt=“AES-128:303132333435363733839303132333435:3534333231303938373635