C# Rijndael加密
我有一个使用C#.NET Rijndael加密的示例代码,它可以解密密文“fggsuwq1gtox40dfgdfgffdfgdfgfczer3woenxtmpmn9jjc”到普通的“75.117.87.87” 我已尝试将保留方法写入加密纯文本“75.117.87.87”到“FGGSUWQ1GTOX40DFGDFGFDFGDFCzer3WOENXTMPN9JJC”,但未成功(加密文本与预期不同-,但结果如附件所示。请帮助我,谢谢C# Rijndael加密,c#,encryption,cryptography,rijndael,C#,Encryption,Cryptography,Rijndael,我有一个使用C#.NET Rijndael加密的示例代码,它可以解密密文“fggsuwq1gtox40dfgdfgffdfgdfgfczer3woenxtmpmn9jjc”到普通的“75.117.87.87” 我已尝试将保留方法写入加密纯文本“75.117.87.87”到“FGGSUWQ1GTOX40DFGDFGFDFGDFCzer3WOENXTMPN9JJC”,但未成功(加密文本与预期不同-,但结果如附件所示。请帮助我,谢谢 static int Main(string[] args)
static int Main(string[] args)
{
Decrypt();
Console.WriteLine("########################");
Console.WriteLine("########################");
Encrypt();
Console.ReadLine();
return 0;
}
public static void Decrypt()
{
string ciphertext = "LkbsUwQ1gToX40dYXizgc0BCCCzEr3wOenxTPMN9jJC";
string secretkey = "11111111";
string saltkey = "thekey";
string result = rijndaelDecrypt(ciphertext, secretkey, saltkey);
Console.WriteLine("Cipher text: " + ciphertext);
Console.WriteLine("Decrypted text: " + result);
return;
}
public static string rijndaelDecrypt(string ciphertext, string secretkey, string saltkey)
{
if (string.IsNullOrEmpty(ciphertext))
{
return null;
}
if (string.IsNullOrEmpty(secretkey))
{
return null;
}
ciphertext = "EAAAA" + ciphertext;
RijndaelManaged rijndaelManaged = null;
string result = null;
try
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(secretkey, Encoding.ASCII.GetBytes(saltkey));
byte[] buffer = Convert.FromBase64String(ciphertext);
MemoryStream memoryStream = new MemoryStream(buffer);
rijndaelManaged = new RijndaelManaged();
rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
rijndaelManaged.IV = rb(memoryStream);
ICryptoTransform transform = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
StreamReader streamReader = new StreamReader(cryptoStream);
result = streamReader.ReadToEnd();
}
catch (Exception)
{
if (rijndaelManaged != null)
{
rijndaelManaged.Clear();
}
return null;
}
finally
{
if (rijndaelManaged != null)
{
rijndaelManaged.Clear();
}
}
return result;
}
public static void Encrypt()
{
string ciphertext = "75.117.87.87";
string secretkey = "1111111";
string saltkey = "thekey";
string result;
RijndaelManaged rijndaelManaged = new RijndaelManaged();
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(secretkey, Encoding.ASCII.GetBytes(saltkey));
rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
byte[] buffer = EncodeToBytes(ciphertext);
MemoryStream memoryStream = new MemoryStream(buffer);
rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
//rijndaelManaged.IV = rb(memoryStream);
ICryptoTransform transform = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
StreamReader streamReader = new StreamReader(cryptoStream);
result = streamReader.ReadToEnd();
var encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
var msEncrypt = new MemoryStream();
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
swEncrypt.Write(result);
result = Convert.ToBase64String(msEncrypt.ToArray());
Console.WriteLine("Plain text: " + ciphertext);
Console.WriteLine("Encrypted text: " + result);
return;
}
private static byte[] rb(Stream s)
{
byte[] array = new byte[4];
if (s.Read(array, 0, array.Length) != array.Length)
{
return null;
}
byte[] array2 = new byte[BitConverter.ToInt32(array, 0)];
if (s.Read(array2, 0, array2.Length) != array2.Length)
{
return null;
}
return array2;
}
private static byte[] EncodeToBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
您使用的是不同的IVs。对于解密方法,您使用的是base64解码密文:
byte[] buffer = Convert.FromBase64String(ciphertext);
MemoryStream memoryStream = new MemoryStream(buffer);
rijndaelManaged.IV = rb(memoryStream);
对于您的加密方法,您使用PBKDF2(Rfc2898DeriveBytes)从密码中派生它,当且仅当您使用随机salt构造Rfc2898DeriveBytes
时,这是正确的方法。
或者,您可以使用RNGCryptoServiceProvider
获得完全随机的IV
rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
从安全角度来看,您应该使用随机salt来派生密钥/IV,并在加密时将其预编到密文中。对于解密,您应该再次将其切断(并将其用于派生解密密钥/IV)。我在您的代码中没有看到任何试用:)我没有看到任何加密方法的尝试。当问“为什么X不工作?”时,请确保至少显示X的代码。当您解释您尝试的内容时,这会更好。@domi1819:我已经更新了加密方法和图像,谢谢您的关注!我认为问题在于Encryption methodI中的初始化向量被否决了,因为从KDF派生IV不是你要做的,因为在使用同一密钥进行加密时,你最终会得到一个静态IV。IVs应该总是用CSPRNG随机生成。@LukePark如果可以的话,我会否决你的评论,因为使用随机盐时,从KDF派生IVs是很好的。(这就是为什么我提出了关于随机盐的安全建议,你应该一直这样做)我想你误解了。我并不是说生成的IV不合适。我反对你的笼统说法“对于你的加密算法,你是从密码中推导出来的……这是正确的做法。”。这不是正确的做法,而且具有误导性。在这种情况下,在这些特定情况下,它会产生可接受的结果。但是,将代码更改为重用AES实例会立即带来问题。如果每次代码只是随机生成IV,那么不可能通过更改其他区域的代码来引入错误。更具体地说,回想一下StackOverflow的目的是帮助其他人,就像帮助OP一样。如果不太精通密码学的人阅读了您关于从与密钥相同的KDF派生IV的建议,该怎么办?非常误导。我希望你能理解我的意思,只要用一个CSPRNG就行了。