Obecnie pracuję nad implementacją AES w języku C#. Metoda szyfrowania ma dwa parametry: ciąg znaków i hasło. Biorę podany ciąg i konwertuję go na tablicę bajtów, więc mogę użyć go później do zapisu danych do strumienia z BinaryWriter
.Jak poprawnie i spójnie uzyskać bajty z ciągu znaków dla szyfrowania AES?
Problem polega na tym, że gdy używam Convert.FromBase64String(string)
, otrzymuję FormatException: Invalid length.
i gdy używam Encoding.UTF8.GetBytes(string)
, moja metoda odszyfrowywania wyrzuca i jest niepoprawny wyjątek PKCS7.Padding.
Próbuję rozwiązać ten problem przez ostatnie kilka dni. Czytałem w pobliżu nieskończonych pytań w stackoverflow.com i innych witrynach internetowych, ale nadal nie wiem, co jest najbardziej niezawodnym sposobem rozwiązania tego problemu.
Łańcuchy, które będą używane w tym programie, są ograniczone do zdań (np. "Coś do zaszyfrowania") i numerów (np. "12345").
Dziękuję z góry, oto kod mam w tym momencie: oczekuje się, aby otrzymać ciąg generowany przez Convert.ToBase64String(byte[]);
przechodzącej w dowolny tekst nie będzie działać
public class AESProvider {
public byte[] EncryptStringToBytes_Aes(string plainText, string Key)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
byte[] plainTextInBytes = Convert.FromBase64String(plainText);
byte[] encrypted;
//Create an Aes object
//with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.GenerateIV();
byte[] IV = aesAlg.IV;
//The Salt will be the first 8 bytes of the IV.
byte[] theSalt = new byte[8];
Array.Copy(IV,theSalt,8);
//A key for AES is generated by expanding the password using the following method.
Rfc2898DeriveBytes keyGen = new Rfc2898DeriveBytes(Key,theSalt);
byte[] aesKey = keyGen.GetBytes(16);
aesAlg.Key = aesKey;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (BinaryWriter swEncrypt = new BinaryWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainTextInBytes);
}
encrypted = msEncrypt.ToArray();
}
}
// Prepend the IV to the ciphertext so it can be used in the decryption process.
using (MemoryStream ivPlusCipher = new MemoryStream())
{
using (BinaryWriter tBinaryWriter = new BinaryWriter(ivPlusCipher))
{
tBinaryWriter.Write(IV);
tBinaryWriter.Write(encrypted);
tBinaryWriter.Flush();
}
return ivPlusCipher.ToArray();
}
}
}
public byte[] DecryptStringFromBytes_Aes(byte[] cipherText, string Key)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
byte[] decrypted;
// Create an Aes object
// with the specified key and IV.
// Create the streams used for decryption.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.CBC;
aesAlg.Padding = PaddingMode.PKCS7;
//Grab IV from ciphertext
byte[] IV = new byte[16];
Array.Copy(cipherText,0,IV,0,16);
//Use the IV for the Salt
byte[] theSalt = new byte[8];
Array.Copy(IV,theSalt,8);
Rfc2898DeriveBytes keyGen = new Rfc2898DeriveBytes(Key,theSalt);
byte[] aesKey = keyGen.GetBytes(16);
aesAlg.Key = aesKey;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, IV);
using (MemoryStream msDecrypt = new MemoryStream())
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
using (BinaryWriter srDecrypt = new BinaryWriter(csDecrypt))
{
//Decrypt the ciphertext
srDecrypt.Write(cipherText, IV.Length, (cipherText.Length - IV.Length));
}
decrypted = msDecrypt.ToArray();
return decrypted;
}
}
}
}
}
twoje 'DecryptStringFromBytes' nie zwraca ciąg znaków, dlaczego? –
Najważniejszym pytaniem jest i pozostanie: co znajduje się w łańcuchu wejściowym, który ma odszyfrować. Mam na myśli, że jeśli jest to heksadecymal, to żadna odpowiedź nie będzie poprawna. Proszę podać przykład! –
Dziękujemy za dane wejściowe. Przykłady ciągów, które już dodano w pytaniu! – Mandos