C#: AES erreur: Rembourrage est pas valide et ne peut pas être supprimé. Même clé et tout et tout, aider
Je suis assez novice en C#, donc s'il vous plaît être patient avec moi. Je sais que cette question a été posé beaucoup à une époque, mais je ne pouvais pas trouver une réponse à mon problème.
Je l'enregistrement des données et avant de les écrire dans un fichier, je le convertir en binaire et de le stocker dans le tableau, à qui j'ai chiffrer et puis les écrire dans un fichier. Je crypter les données en segments (32 octets). De la même manière, j'ai lu les données en blocs de 32 octets et puis déchiffrer les données et ensuite cela devrait répéter jusqu'à la fin du fichier. Mais quand il s'agit de décryptage de l'erreur suivante est générée:
Rembourrage est pas valide et ne peut pas être supprimé.
- Je utiliser la même clé et iv (codé en dur jusqu'à ce que je l'obtenir à travailler)
Voici mon code de cryptage, qui fonctionne sans problèmes:
//result
byte[] data = new byte[32];
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9,50};
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
FileStream fStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
//prepare data to write (byte array 'data') ...
//encrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
data = m.ToArray();
fStream.Write(data, 0, data.Length);
Et voici mon code de déchiffrement:
FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);
//result
byte[] data = new byte[32];
//loop for reading the whole file ...
int len = fStream.Read(data, 0, 32);
//decrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length); //The exception is thrown in this line
data = m.ToArray();
//using the decrypted data and then looping back to reading and decrypting...
J'ai essayé tout ce que je pouvais penser (ce qui n'est pas beaucoup parce que je suis très nouveau à la cryptographie), j'ai cherché partout et je ne pouvais pas trouver une solution à mon problème. J'ai aussi aidé moi-même avec le livre C# en Bref .
Si quelqu'un a des idées sur le pourquoi de ce qui pourrait arriver, je serai vraiment reconnaissante car je n'ai pas d'idées.
Je vous remercie pour votre temps et vos réponses.
EDIT:
Il semble que la taille des données chiffrées est de 48 octets (12 octets de plus que l'original). Pourquoi donc? J'ai pensé qu'il ajoute des octets si elles ne sont pas un multiple de la taille des blocs de 16 octets, mes données est de 32 octets). Données toujours plus grands, et avec la constante augmentation (j'ai besoin de savoir que pour bien lire et déchiffrer).
Note: je ne peux pas utiliser directement les autres cours d'eau parce que j'ai besoin d'avoir le contrôle sur le format de sortie et je crois que c'est aussi plus sûr et le plus rapide pour chiffrer dans la mémoire.
- Je pense que Ben est ici, pouvez-vous vérifier le fichier pour voir la sortie des données chiffrées (ie, est le fichier binaire de 32 octets?). Vous aurez envie de lire dans le fichier tout entier et que décrypter.
- autres @Ben: 48 octets 16 octets de plus que votre entrée, et non pas 12. Ce qui vous empêche de simplement en utilisant la longueur du flux crypté? Il ne devrait prendre que quelques octets supplémentaires pour sauver la longueur quelle que soit la structure/wrapper enveloppe/pdu les données chiffrées sont incorporées.
- J'ai vérifié sur le tableau après le cryptage et juste avant d'écrire sur le fichier et il était de 48 octets, oui, 16 non 12 =). Je ne peux pas parce que parfois, les fichiers peuvent devenir vraiment grand et je vais avoir besoin d'un seul bloc de données à partir d'un endroit que je vais calculer et donc je dois être capable de décrypter un fichier dans le bloc-comme la mode. @Ben Voigt bien si elle a toujours (pour la même taille de bloc) crée le même "incrémenter" en taille, alors je peux m'adapter, mais je trouve un gaspillage de l'espace en tant que ces choses s'additionnent rapidement.
- Du sens. Je pense que je serait à son tour rembourrage dans cette affaire, sinon vous ne saurez jamais où pour la lecture.
Vous devez vous connecter pour publier un commentaire.
Basé sur votre edit:
Si les données cryptées est de 48 octets, c'est de 16 octets, plus grand que l'original de votre tableau. Cela a un sens parce que l'algorithme avec un tampon de données, car la valeur par défaut est PKCS7 (même si la taille correspond à la taille de bloc, parce qu'il coussinets à l' prochaine multiple de celle du bloc de taille). Si vous souhaitez le conserver exactement 32 octets, il suffit de changer le Rembourrage à Aucun
Vous semble être le traitement de la longueur du texte en clair que la longueur du texte chiffré. Ce n'est pas une hypothèse sûre.
Pourquoi êtes-vous de la copie entreFileStream
etMemoryStream
, vous pouvez passer uneFileStream
directement à la encryptor/decryptor.Dans PKCS7, il y a un minimum de rembourrage octet (pour stocker le nombre d'octets de remplissage). De sorte que la taille de sortie sera
Ceil16(input.Length + 1)
, ou(input.Length & ~15) + 1
.Court, c'est que AES chiffre les messages dans des blocs de 16 octets. Si votre message n'est pas un multiple de 16 octets, l'algorithme doit être un peu différent pour le dernier bloc; en particulier, le dernier bloc doit être "collier" avec une valeur connue à l'algorithme une valeur de remplissage (généralement zéro, parfois, quelque chose d'autre, comme un espace de valeur de caractère).
Que vous faites vous-même, en mettant les données dans une longueur fixe tableau d'octets. Vous collier de données vous-même, mais le decrypter est en train d'essayer de pad le dernier bloc et l'obtention de valeurs d'octets qu'il ne reconnaît pas comme le rembourrage que l'encryption de ses homologues ont ajouté.
La clé est de ne pas compléter le message. Vous pouvez utiliser le BitConverter classe de jeter des tableaux d'octets et de IConvertible types (types de valeur et de chaînes de caractères), et ensuite l'utiliser à la place de roulement de votre propre tableau d'octets. Ensuite, lorsque vous déchiffrer, vous pouvez lire le décryptage de flux jusqu'à la longueur du texte chiffré, mais ne pas s'attendre à ce que de nombreux octets dans la restitution des résultats.