2010-07-11 10 views
4

joue autour avec le cryptage et le décryptage des fichiers dans VC# Express 2010.C# File Encryption et numéro Decryption

Tous les didacticiels et la documentation que j'ai vus nécessite deux FileSteams afin de chiffrer le fichier. Un pour lire la version non cryptée et l'autre pour crypter. Lorsque j'ai réellement écrit le code, il continuait à me lancer une erreur me disant qu'il ne pouvait pas ouvrir le fichier car il était ouvert par un autre processus au niveau du flux de sortie.

Je suppose que c'est parce que le fichier est ouvert par le flux de fichiers d'entrée. Cela signifie donc que je dois spécifier un nom de fichier différent? Donc, même après l'opération réussie, je sais que le fichier non crypté d'origine dans le répertoire et une version cryptée séparée? Cela ne va-t-il pas à l'encontre du but? Ou est-ce que je fais quelque chose de mal ici? Mon code est similaire à ceci ...

public string filename = "test.xml"; 
using(FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read)) 
using(FileStream output = new FileStram(filename, FileMode.Open, FileAccess.Write)) 
using(....all the crypto stream and transform stuf...) 
{ 
    ...do the encryption.... 
} 

Répondre

0

Utilisez File.ReadAllBytes. Ensuite, les octets envoyés à votre chiffreur doivent fonctionner.

3

Vous avez raison, mais cela ne va pas à l'encontre du but. Les API de cryptage (en continu) sont destinées à crypter de Src à Dst. Pensez à crypter la sortie tout en envoyant/recevant sur un réseau, etc. Cela les garde simples, comme ils devraient l'être.

Vous compliquez le problème en utilisant le même fichier pour Src et Dst. Ce n'est pas totalement impossible, mais comme Copier un fichier sur lui-même, il a besoin de plus de précautions. Considérons qu'en général, le cryptage augmentera la taille du fichier. Il n'est donc pas sûr de chiffrer un fichier en place. Décrypter pourrait être, mais je ne le risquerais pas.

Ce dont vous avez besoin est un fichier Temp et une action de renommer après l'achèvement.

+0

Cela touche à un autre problème: votre fichier n'est pas sûr si l'attaquant a accès à votre ordinateur en cours d'exécution.Si vous souhaitez crypter le fichier, vous devez vous assurer que les octets non cryptés ne touchent jamais le disque dur. Si vous ouvrez votre business plan super secret, toutes sortes de fichiers temporaires vont être écrits sur le disque que vous ne pourrez jamais nettoyer. Si vous cherchez à protéger un fichier, vous avez vraiment besoin d'un cryptage complet. – TwentyMiles

1

Dans votre exemple, vous ne pouvez pas créer un flux de fichiers séparé pour l'entrée et la sortie sur le même fichier, mais vous pouvez créer un handle qui va lire et écrire. L'enum FileAccess a l'attribut flags, donc vous devez simplement dire var handle = new FileStream(filename, FileAccess.Read | FileAccess.Write); L'inconvénient évident de ceci est que vous allez avoir des données perdues si votre chiffrement ne se termine pas avec succès.

Je recommande d'avoir un fichier séparé pour la sortie, au moins de cette façon, vous ne perdrez pas de données si votre programme se brise de façon inattendue. Si le chiffrement se termine avec succès, supprimez l'original et renommez le fichier chiffré avec le nom de fichier d'origine.

+0

Est-ce ainsi que fonctionnent les autres applications de chiffrement de fichiers? Je n'ai jamais vu une copie résiduelle de la source non cryptée après une opération de cryptage. Je devrais sortir dans un fichier temporaire .... créer une instruction if pour surveiller le succès de l'opération, puis si elle est réussie, puis supprimer l'original et renommer le temporaire afin de le remplacer? Cela garantit que les données ne sont pas perdues? – Stev0

+0

Voici comment la plupart des applications fonctionnaient dans la journée. Je ne suis pas sûr maintenant. Les fichiers temporaires sont généralement masqués et peuvent se trouver dans un dossier temporaire sur le disque. La même idée est utilisée dans le cryptage du système de fichiers - si vous déplacez un fichier vers un système de fichiers crypté, l'original ne sera pas supprimé tant que le déplacement n'aura pas abouti. Vous devez en quelque sorte conserver les données d'origine jusqu'à ce que vous sachiez que le cryptage est terminé avec succès, car cela peut être quelque chose de simple comme un manque de mémoire ou un disque complet qui entraîne l'échec de votre application. –

+0

Si vous avez vraiment besoin de recycler le fichier existant, je vous suggère de le lire en blocs de taille fixe (disons quelque chose comme 4096kb - quelque chose qui va facilement entrer dans la mémoire). Si, et seulement si chaque bloc se termine avec succès, écraser le bloc d'origine, mais sinon, afficher dans un fichier journal la position dans laquelle le fichier est chiffré et toutes les données potentielles pour aider à le récupérer. (c'est-à-dire, vecteurs d'initialisation, clés, cause d'erreur). –

0

Il y a un autre paramètre où vous pouvez spécifier si vous souhaitez autoriser un autre processus de lire ou d'écrire dans le fichier

openFile est le nom du fichier, un type de chaîne.

using (FileStream fileIn = new FileStream(openFile, FileMode.Open, FileAccess.Read, FileShare.Write)) 
using (FileStream fileOut = new FileStream(openFile, FileMode.Open, FileAccess.Write, FileShare.Open)) 

De cette façon, vous pouvez lire et écrire dans le même fichier.

while (myfileStream.Position < fileLength) 
{ 

    fileIn .Read(buffer, 0, 51200); 

    buffer = encrypt(buffer); 

    fileOut .Write(buffer, 0, 51200);     


} 

Bien que c'est facile et vous ne devez pas écrire dans un fichier temporaire ou avoir à se déplacer/renommer etc, cela peut être très dangereux où si les ruptures de chiffrement soudainement pour une raison quelconque, vous perdrez des données ! A

En outre, la fonction de chiffrement est quelque chose que j'ai implémenté. AesCryptoServiceProvider avec CryptoStream peut être utilisé :)

+1

Je pense que votre condition est cassé. Mais pire, la position de fileOut va commencer à dépasser celle de fileIn, et votre fichier sera brouillé au-delà de toute réparation. –

+0

@Henk: Oui. Vous avez raison. Mais le problème était dans les appareils mobiles, si quelqu'un veut chiffrer un fichier de 500 Mo, la création d'un autre fichier de 500 Mo serait impossible en raison de contraintes de ressources. J'admets que c'est dangereux et peut-être défectueux, mais quelque chose de ce genre doit être fait pour les appareils à ressources limitées, n'est-ce pas? Y a-t-il une autre approche? :) –

+1

L'OQ ne mentionne pas Mobile, donc votre extension du problème ici. Vous pourriez être en mesure de résoudre la situation sans un fichier temp en ajoutant une compression au mélange. Mais ce n'est pas garanti (il se cassera si le fichier Src n'est pas assez compressible, c'est-à-dire déjà compressé). –