Я написал методы шифрования/дешифрования, используя RC2CryptoServiceProvider
в С#, и по какой-то причине я не могу заставить дешифратор расшифровать последние несколько байтов. Файл, похоже, просто отключен. Мой метод шифрования выглядит следующим образом:
public static byte[] EncryptString(byte[] input, string password)
{
PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
byte[] ivZeros = new byte[8];
byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);
RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();
byte[] IV = new byte[8];
ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
csEncrypt.Write(input, 0, input.Length);
csEncrypt.FlushFinalBlock();
return msEncrypt.ToArray();
}
Пока мое дешифрование выглядит следующим образом:
public static byte[] DecryptString(byte[] input, string password, int originalSize)
{
PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
byte[] ivZeros = new byte[8];
byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);
RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();
byte[] IV = new byte[8];
ICryptoTransform decryptor = RC2.CreateDecryptor(pbeKey, IV);
MemoryStream msDecrypt = new MemoryStream();
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write);
csDecrypt.Write(input, 0, originalSize);
// csDecrypt.FlushFinalBlock();
char[] decrypted = new char[input.Length];
decrypted = System.Text.Encoding.UTF8.GetChars(msDecrypt.ToArray());
return msDecrypt.ToArray();
}
char [] decrypted
возвращает весь файл, дешифрованный, за исключением того, что файл заканчивается на </LudoData>
, а при расшифровке я получаю только первый символ <
.
Я играю с вещами и ничего не меняет. В моем конкретном случае input
имеет длину 11296, а originalSize
имеет размер 11290. Однако decrypted
заканчивается размером 11280 при расшифровке. Что дает!
Есть ли причина, по которой вы отключили флеш()? Вы пытались полностью закрыть свои потоки?
Вздох, я сражался с этой битвой около месяца назад и имел очень схожую проблему, за исключением того, что в конце концов я много переживал. ToArray было моим решением.
Вы делаете некоторые странные вещи здесь, я не совсем уверен. Вы используете криптострелики, когда вам этого не нужно, вы отслеживаете исходную длину по какой-то странной причине, и вы используете устаревшие классы. Ваша проблема, вероятно, представляет собой комбинацию отступов, неправильных допущений (подтверждается originalLength) и неправильной обработки потоков (что может быть сложно). Вместо этого попробуйте:
Шифрование:
var rij = RijndaelManaged.Create();
rij.Mode = CipherMode.CBC;
rij.BlockSize = 256;
rij.KeySize = 256;
rij.Padding = PaddingMode.ISO10126;
var pdb = new Rfc2898DeriveBytes(password,
Encoding.Default.GetBytes("lolwtfbbqsalt" + password));
var enc = rij.CreateEncryptor(pdb.GetBytes(rij.KeySize / 8),
pdb.GetBytes(rij.BlockSize / 8));
return enc.TransformFinalBlock(unencryptedBytes, 0, unencryptedBytes.Length);
Расшифровать:
// throws a cryptographic exception if password is wrong
var rij = RijndaelManaged.Create();
rij.Mode = CipherMode.CBC;
rij.BlockSize = 256;
rij.KeySize = 256;
rij.Padding = PaddingMode.ISO10126;
var pdb = new Rfc2898DeriveBytes(password,
Encoding.Default.GetBytes("lolwtfbbqsalt" + password));
var dec = rij.CreateDecryptor(pdb.GetBytes(rij.KeySize / 8),
pdb.GetBytes(rij.BlockSize / 8));
return dec.TransformFinalBlock(encryptedBytes, 0,
encryptedBytes.Length);
Обратите внимание, что единственное, что отличается от этих двух методов, это CreateEncryptor/CreateDecryptor, поэтому вы можете реорганизовать много дублирования. Также обратите внимание, что я попадаю в массив байтов и выхожу из массива байтов без использования каких-либо потоков. Это также немного более безопасно, чем RC2, и, тем более, если соль была бы более случайной.