7
votes

Lecture d'un cryptostream à la fin du ruisseau

J'ai des problèmes avec le code ci-dessous. J'ai un fichier dans un emplacement temporaire qui a besoin de cryptage, cette fonction crypte ces données qui sont ensuite stockées à l'emplacement "pathtosave".

sur inspection est ne semble pas manipuler le fichier entier correctement - il y a bits manquants de ma sortie et je soupçonne que cela a quelque chose à voir avec la boucle tandis que de ne pas courir dans l'ensemble du ruisseau.

comme un de côté, si j'essaie d'appeler Cryptstrm.frose () après la boucle tandis que je recevoir une exception. Cela signifie que si je tente de déchiffrer le fichier, je reçois déjà un fichier d'utilisation!

essayé tous les habituels et ive regardé ici à des problèmes similaires, toute aide serait formidable.

merci xxx

éditer :

J'ai fait l'hypothèse que mon problème est avec le cryptage. Mon déchiffrement pourrait être le coupable xxx


0 commentaires

3 Réponses :


18
votes

Eh bien, il y a plusieurs choses qui ne vont pas mal ici.

1. Votre réglage de la taille du IV trop grand. Si vous avez une taille de clé de 256, IV pour Rijndael est de 16 octets. Si vous essayez de définir la touche avec plus d'octets que vous obtiendrez une exception. Strike> IV Taille doit être réglé sur la taille du bloc / 8 Voir MSDN de sorte que la taille IV que vous avez est correcte. p>

  1. Vous avez un mode de rembourrage de personne. À moins que vos données soient exactement la taille de bloc correcte, vous allez avoir des problèmes. Vous voulez probablement choisir un mode de rembourrage. LI>
  2. Vous devez généralement appeler FlushfinalBlock lors de la rédaction du flux de crypto lorsque vous cryptez pour que toutes les données soient écrites au flux. LI> OL>

    Je pose un exemple de code à l'aide des flux de mémoire pour afficher le cryptage et le déchiffrement. P>

    var tempData = "This is the text to encrypt. It's not much, but it's all there is.";
    
    using (var rijCrypto = new RijndaelManaged())
    {
        byte[] encryptedData;
        rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
        rijCrypto.KeySize = 256;
    
        using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
        using (var output = new MemoryStream())
        {
            var encryptor = rijCrypto.CreateEncryptor();
    
            using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
            {
                var buffer = new byte[1024];
                var read = input.Read(buffer, 0, buffer.Length);
                while (read > 0)
                {
                    cryptStream.Write(buffer, 0, read);
                    read = input.Read(buffer, 0, buffer.Length);
                }
                cryptStream.FlushFinalBlock();
                encryptedData = output.ToArray();
            }
        }
    
        using (var input = new MemoryStream(encryptedData))
        using (var output = new MemoryStream())
        {
            var decryptor = rijCrypto.CreateDecryptor();
            using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
            {
                var buffer = new byte[1024];
                var read = cryptStream.Read(buffer, 0, buffer.Length);
                while (read > 0)
                {
                     output.Write(buffer, 0, read);
                     read = cryptStream.Read(buffer, 0, buffer.Length);
                }
                cryptStream.Flush();
                var result = Encoding.Unicode.GetString(output.ToArray());
            }
        }
    }
    


15 commentaires

Merci PSTRJDS - J'ai apporté des changements mais j'ai toujours des problèmes. IV est maintenant 16 octets, le rembourrage est de zéros et j'ai changé ma boucle tandis que vous pouvez ressembler davantage à votre suggestion, mais je suis toujours errant lorsque j'appelle FlushfinalBlock - "La méthode a été appelée deux fois sur Cryptostream. Il ne peut être appelé qu'une seule fois" . Je ne fais pas confiance que cela a été appelé en premier lieu!


Eh bien, vous devriez seulement appeler flushfinalblock en dehors de la boucle comme la dernière chose à laquelle vous cryptez. Vous n'avez pas besoin de l'appeler lorsque vous déchiffrez, lorsque vous déchiffrez, appelez simplement FUSH. Votre taille de bloc doit être correcte lorsque vous décryptez, il n'aurai aucun rembourrage supplémentaire. En ce qui concerne la confiance, si cela a été appelé, vous pouvez exécuter votre code sous un débogueur et définir un point de pause à cette ligne. Si cela ne frappe pas, il n'a pas été appelé.


Si vous avez une taille de clé de 256, le IV pour Rijndael est de 16 octets. Si vous essayez de définir la clé avec plus d'octets que vous obtiendrez une exception. Ceci est incorrect, si vous avez un blocsize = 256 , votre IV devrait être 32. S'ils sont Ne correspond pas correctement, vous obtiendrez une exception.


@Trisped - bonne prise. Je l'ai réparé et ajouté un lien vers la documentation sur le réglage du rapport de taille de blocsize / IV.


Ce code ne semble même pas fonctionner. Je m'attendais à voir la chaîne d'origine sortir la fin, mais quand je l'exécute, la chaîne déchiffrée ressemble à beaucoup de personnages asiatiques. Pourquoi?


@OBIWAN - Êtes-vous sûr de copier le code et de l'utiliser tel qu'il est? Je viens de le retester et ça a bien fonctionné pour moi. Le résultat String contenait la chaîne d'origine déchiffrée. Le seul changement que je ferais probablement pour le code maintenant, est-ce que j'instésite comme UTF8 au lieu d'unicode. Ce n'est pas bien formaté, mais voici un IDEONE Lien vers le code, le montrant de fonctionner.


.NET 4.7 Ce code donne ce message: Message: System.security.Cryptography.cryptographiceXception: le rembourrage n'est pas valide et ne peut pas être supprimé.


@Richardgriffiths - Je viens de courir ce code sous la version 4.7 et n'a eu aucune exception.


Je vais poster une question séparée comme je viens de VB et j'ai trouvé la plupart des questions à ce sujet jusqu'à présent, ne vous plus rapprochés. C'est très perplexe.


Je ne sais pas si ce sont les mauvaises manières de lien vers ma question ici si d'excuses à l'avance! Stackoverflow.com/Questtions/474777421/...


@Richardgriffiths - J'ai répondit Votre question avec un échantillon de travail.


Merci, je suis juste avant de rentrer à la maison maintenant.


@pstrjds - Ce code fonctionne bien, mais si le code est coupé en deux, de sorte que vous ayez l'aide (Var Rijcrypto = Nouveau Rijndaelmanaged ()) pour crypter (et que vous stockez la clé et IV de Rijcrypto dans des variables), puis une autre utilisation ( Var Rijcrypto = Nouveau Rijndaélanné ()) Pour le déchiffrement, définir la clé et iv, je reçois l'exception de rembourrage. Quoi d'autre doit être maintenu pour déchiffrer correctement?


@pstrjds - Je viens de faire plus de débogage. Je l'ai eu pour travailler en deux morceaux simplement en utilisant le rembourrage par défaut (PKCS7) plutôt que ISO10126, comme spécifié dans le code. Y a-t-il une raison de choisir ISO10126? Merci pour le code cependant, fonctionne bien merci!


@Dombat - Lien Ideone à un échantillon de travail où vous utilisez un objet distinct rijndaelmanaged objet pour crypter et déchiffrer (enregistrer la navigation IV et la clé du cryptage et l'utilisation de la clé IV et de la touche enregistrée pour le déchiffrement). Aucune exception de rembourrage, tout fonctionne bien. J'ai choisi ISO10126 parce que je préfère le rembourrage avec des données aléatoires.



-1
votes

La touche de frappe doit être spécifiée en premier. Cela ressemble à un bug ex. Cela fonctionne xxx

mais ce n'est pas xxx


1 commentaires

Cela ne traite pas du tout à la question des OPS.



2
votes

Une autre façon de lire Cryptostream est d'utiliser la copieTo méthord: xxx


0 commentaires