Wie man richtig und consistely bekommen bytes aus einem string für die AES-Verschlüsselung?
Ich bin momentan auf der AES-Implementierung in C#. Die Verschlüsselungs-Methode hat zwei Parameter: einen string und ein Passwort. Ich nehme den mitgelieferten string und konvertieren es in ein array von bytes, damit ich Sie später für das schreiben von Daten in einen stream mit BinaryWriter
.
Das problem ist, dass wenn ich Convert.FromBase64String(string)
bekomme ich FormatException: Invalid length.
und wenn ich Encoding.UTF8.GetBytes(string)
mein Entschlüsselungs-Methode wirft und ungültige PKCS7.Polsterung Ausnahme.
Habe ich versucht, dieses problem zu lösen, für die letzten paar Tage. Ich habe gelesen in der Nähe von unendlichen Fragen in stackoverflow.com und anderen websites, aber ich weiß noch nicht, was ist der zuverlässigste Weg, um dieses problem zu lösen.
Zeichenfolgen, die verwendet werden in diesem Programm sind begrenzt auf die Sätze (ex. "Etwas zu verschlüsseln.") und zahlen (ex. "12345").
Vielen Dank im Voraus, hier ist der code, den ich haben an diesem Punkt in der Zeit:
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;
}
}
}
}
}
- Ihre
DecryptStringFromBytes
nicht einen string zurückgeben, warum? - Die wichtigste Frage ist und bleibt: was wird in den input-string, die Sie angeblich zu entschlüsseln. Ich meine, wenn es hexadezimal dann keine Antwort wird richtig sein. Bitte geben Sie ein Beispiel!
- Danke für den input. Beispiele für strings, wo bereits Hinzugefügt, in der Frage!
- Gut, dass die Antwort von Rasmus viel leichter zu prüfen und die Abstimmung auf.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie die Konvertierung zwischen bytes und strings vor und nach der Verschlüsselung/Entschlüsselung. Dies ist nicht die gleiche operation, und Sie sollten nicht verwenden Sie die gleiche Methode.
Beim verschlüsseln Sie beginnen mit einer beliebigen Zeichenfolge. Konvertieren Sie diese in ein byte[] mit
Encoding.UTF8.GetBytes()
. Die Verschlüsselung. Die daraus resultierende byte[] kann nun in einen string umgewandelt, mitConvert.ToBase64String()
.Beim entschlüsseln beginnen Sie nun mit ein, die eine Base64-codierte Zeichenfolge. Decodieren Sie diese in ein byte[] mit
Convert.FromBase64String()
. Sie entschlüsseln. Sie haben nun die UTF-8-Codierung, die Ihre ursprüngliche Zeichenfolge, die Sie Dekodieren kann mitEncoding.UTF8.GetString()
.Denken Sie daran:
Blick auf Ihre Linien
Beliebigen Klartext wird nicht sein, eine base-64-codierte Zeichenfolge. Auch wenn es sein soll, base 64-kodierter text, deine Fehlermeldung zeigt an, dass die Länge nicht teilbar durch 4
http://msdn.microsoft.com/en-us/library/system.convert.frombase64string(v=vs. 110).aspx
Wenn es ist eine base-64-codierte Zeichenfolge, müssen Sie die pad es accorgingly
http://en.wikipedia.org/wiki/Base64
Convert.FromBase64String(string);
wird erwartet, zu bekommen ein string generiertConvert.ToBase64String(byte[]);
übergabe einer beliebigen Zeichenkette wird nicht funktionieren.Die einfachste Lösung ist, ersetzen Sie die
BinaryWriter
undBinaryReader
mit einemStreamWriter
und einStreamReader
und nicht an der Konvertierung.Auch, Ihre Entschlüsselung ist die Funktion tatsächlich versuchen, verschlüsseln Sie den text ein 2. mal zu bekommen, muss man das byte-array an den Konstruktor von
msDecrypt
und steckte es in die Entschlüsselung Modus.Es können auch andere Fehler mit dem code, aber zumindest bekommt Sie auf dem richtigen Weg.
msEncrypt.Write(IV, 0, IV.Length);
und dann wieder in Ihre alte block, in dem Sie kopiert die IV in.