gpt4 book ai didi

c# - 在 C# 中使用 Rijndael 解密

转载 作者:行者123 更新时间:2023-11-30 20:56:32 25 4
gpt4 key购买 nike

我有以下加密方法。我无法解密它。我继承了加密算法,无法更改。

public static string Encrypt(string plaintext)
{
byte[] rgbIV;
byte[] key;

RijndaelManaged rijndael = BuildRigndaelCommon(out rgbIV, out key);

//convert plaintext into a byte array
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);

int BlockSize;
BlockSize = 16 * (1 + (plaintext.Length / 16));
Array.Resize(ref plaintextBytes, BlockSize);

// fill the remaining space with 0
for (int i = plaintext.Length; i < BlockSize; i++)
{
plaintextBytes[i] = 0;
}

byte[] cipherTextBytes = null;
//create uninitialized Rijndael encryption obj
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
var transform = rijndael.CreateEncryptor();

//Chaining mode
symmetricKey.Mode = CipherMode.CFB;

//create encryptor from the key and the IV value
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);

//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream())
{
//define cryptographic stream - contains the transformation key to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
//encrypt contents of cryptostream
cs.Write(plaintextBytes, 0, BlockSize);
cs.FlushFinalBlock();

//convert encrypted data from a memory stream into a byte array
cipherTextBytes = ms.ToArray();
}
}
}

//store result as a hex value
string hexOutput = BitConverter.ToString(cipherTextBytes).Replace("-", "");
hexOutput = hexOutput.Substring(0, plaintext.Length * 2);

//finially return encrypted string
return hexOutput;
}

如您所见,它非常标准,除了最后它被转换为十六进制并执行子字符串。我很难做相反的事情。

我的解密方法是这样的:

     public static string Decrypt(string disguisedtext)
{
byte[] rgbIV;
byte[] key;

BuildRigndaelCommon(out rgbIV, out key);

byte[] disguishedtextBytes = FromHexString(disguisedtext);

string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
//create encryptor from the key and the IV value

// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);

//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
{
//define cryptographic stream - contains the transformation to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
{

byte[] plaintextBytes = new Byte[disguishedtextBytes.Length];
cs.Write(disguishedtextBytes, 0, disguishedtextBytes.Length);
cs.FlushFinalBlock();

//convert decrypted data from a memory stream into a byte array
byte[] visiabletextBytes = ms.ToArray();

visiabletext = Encoding.UTF8.GetString(visiabletextBytes);
}
}
}
return visiabletext;
}

辅助方法:

   private static RijndaelManaged BuildRigndaelCommon(out byte[] rgbIV, out byte[] key)
{
rgbIV = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };

key = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };

//Specify the algorithms key & IV
RijndaelManaged rijndael = new RijndaelManaged{BlockSize = 128, IV = rgbIV, KeySize = 128, Key = key, Padding = PaddingMode.None};

return rijndael;
}

public static byte[] FromHexString(string hexString)
{
if (hexString == null)
{
return new byte[0];
}

var numberChars = hexString.Length;
var bytes = new byte[numberChars / 2];

for (var i = 0; i < numberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
}

return bytes;
}

我收到有关字符串长度的各种错误,并且填充无效。有没有人有任何想法让解密工作。我已尝试将输入字符串填充回 32 字节但无济于事。

最佳答案

您的问题是 Encrypt 方法中的一个细微错误。通过弄乱 hexOutput 字符串,您正在丢失返回的密文中的数据。而不是:

//store result as a hex value
string hexOutput = BitConverter.ToString(cipherTextBytes).Replace("-", "");
hexOutput = hexOutput.Substring(0, plaintext.Length * 2);

//finially return encrypted string
return hexOutput;

你应该只返回输出:

return BitConverter.ToString(cipherTextBytes).Replace("-", "");

您还需要将解密方法中的填充模式更改为无。虽然这现在可以正确解密,但它还将包括您在加密方法中添加的手动填充字符。由于您不知道您的纯文本,因此您没有删除它们的好方法。您总是可以添加一种方法来删除数组中与零填充值不匹配的所有字节:

int endMarker = decryptedData.Length;
do { endMarker--; } while (decryptedData[endMarker] == 0);
Array.Resize(ref decryptedData, endMarker + 1);

然而,这并不是一个好主意,因为您可能会丢弃原本有效的数据。更好的解决方案是更新您的加密和解密方法,让密码处理填充。将它们放在一起我们得到(仅显示我所做的更改):

private static RijndaelManaged BuildRigndaelCommon(out byte[] rgbIV, out byte[] key)
{
rgbIV = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
key = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };

//Specify the algorithms key & IV
RijndaelManaged rijndael = new RijndaelManaged{BlockSize = 128, IV = rgbIV, KeySize = 128, Key = key, Padding = PaddingMode.PKCS7 };
return rijndael;
}

public static string Encrypt(string plaintext)
{
byte[] rgbIV;
byte[] key;

RijndaelManaged rijndael = BuildRigndaelCommon(out rgbIV, out key);

//convert plaintext into a byte array
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);

byte[] cipherTextBytes = null;

//create uninitialized Rijndael encryption obj
using (RijndaelManaged symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
var transform = rijndael.CreateEncryptor();

//Chaining mode
symmetricKey.Mode = CipherMode.CFB;
//create encryptor from the key and the IV value
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);

//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
//encrypt contents of cryptostream
cs.Write(plaintextBytes, 0, plaintextBytes.Length);
cs.Flush();
cs.FlushFinalBlock();

//convert encrypted data from a memory stream into a byte array
ms.Position = 0;
cipherTextBytes = ms.ToArray();

ms.Close();
cs.Close();
}
}

//store result as a hex value
return BitConverter.ToString(cipherTextBytes).Replace("-", "");
}

public static string Decrypt(string disguisedtext)
{
byte[] disguishedtextBytes = FromHexString(disguisedtext);

byte[] rgbIV;
byte[] key;

BuildRigndaelCommon(out rgbIV, out key);



string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
symmetricKey.BlockSize = 128;

//create encryptor from the key and the IV value

// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);

//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
{
//define cryptographic stream - contains the transformation to be used and the mode
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
byte[] decryptedData = new byte[disguishedtextBytes.Length];
int stringSize = cs.Read(decryptedData, 0, disguishedtextBytes.Length);
cs.Close();

//Trim the excess empty elements from the array and convert back to a string
byte[] trimmedData = new byte[stringSize];
Array.Copy(decryptedData, trimmedData, stringSize);
visiabletext = Encoding.UTF8.GetString(trimmedData);
}
}
}
return visiabletext;
}

希望这可以帮助您指明方向。顺便说一句,我维护 a set of encryption utilities在可能对您有用的 Snipt 上,特别是 SymmetricEncrypt 和 SymmetricDecrypt 方法。

------ 编辑 ------

如以下评论所述,我们不允许更改加密方法。我喜欢一个很好的挑战!应用适当的字节处理后,下面是一个解密,它支持从 Encrypt 方法返回的结果:

public static string Decrypt(string disguisedtext)
{
byte[] disguishedtextBytes = FromHexString(disguisedtext);

var originalLength = disguishedtextBytes.Length;

int BlockSize;
BlockSize = 16 * (1 + (originalLength / 16));
Array.Resize(ref disguishedtextBytes, BlockSize);

// fill the remaining space with 0
for (int i = originalLength; i < BlockSize; i++)
{
disguishedtextBytes[i] = 0;
}


byte[] rgbIV;
byte[] key;

BuildRigndaelCommon(out rgbIV, out key);

string visiabletext = "";
//create uninitialized Rijndael encryption obj
using (var symmetricKey = new RijndaelManaged())
{
//Call SymmetricAlgorithm.CreateEncryptor to create the Encryptor obj
symmetricKey.Mode = CipherMode.CFB;
symmetricKey.BlockSize = 128;
symmetricKey.Padding = PaddingMode.None;

// ICryptoTransform encryptor = symmetricKey.CreateEncryptor(key, rgbIV);
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(key, rgbIV);

//define memory stream to hold encrypted data
using (MemoryStream ms = new MemoryStream(disguishedtextBytes))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
byte[] decryptedData = new byte[disguishedtextBytes.Length];
int stringSize = cs.Read(decryptedData, 0, disguishedtextBytes.Length);
cs.Close();

//Trim the excess empty elements from the array and convert back to a string
byte[] trimmedData = new byte[stringSize];
Array.Copy(decryptedData, trimmedData, originalLength);
Array.Resize(ref trimmedData, originalLength);

visiabletext = Encoding.UTF8.GetString(trimmedData);
}
}
return visiabletext;
}

关于c# - 在 C# 中使用 Rijndael 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17483257/

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