Dzielenie plików, CRC32, hash i szyfrowanie

0

Witam wszystkich. Dosyć długi i obszerny temat..
A więc na początek: zbudowałem dwie metody, jedna służy do dzielenia a druga do scalania plików.
Metody działają dobrze, więc jeśli ktoś chce może sobie poniższy kod "pożyczyć":
Metoda do dzielenia plików: przyjmuje:
-pełną nazwę pliku (np: C:\folder\plik.exe);
-folder, gdzie mają być zapisane części (np: C:\folder);
-na ile MB ma być podzielony plik (np: 4)
Części są zapisywane następująco: plik.exe >> part1: plik.exe.part1.fs itd.

private void SplitFile(string fullname, string wheresave, int whatMB)
        {
            try
            {
                Stream inputStream;
                Stream localStream;
                long whatKB = whatMB * 1024;
                string localFilename;
                FileInfo file = new FileInfo(fullname);
                long size = file.Length / 1024;
                long parts = size / whatKB + 1;
                inputStream = File.OpenRead(file.Name);
                byte[] buffer = new byte[1024];
                int bytesRead;
                for (int a = 1; a < parts + 1; a++)
                {
                    localFilename = wheresave + @"\" + file.Name + ".part" + a + ".fs";
                    localStream = File.Create(localFilename);
                    for (int b = 0; b < whatMB * 1024; b++)
                    {
                        bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                        localStream.Write(buffer, 0, bytesRead);
                    }
                    localStream.Close();
                }
                inputStream.Close();
            }
            catch
            {
                MessageBox.Show("Error!");
                return;
            }
            MessageBox.Show("OK");
        }

Metoda do scalania plików. Przyjmuje:
-pełną nazwę pierwszej części pliku (NP: C:\folder\plik.exe.part1.fs);
-folder, gdzie ma być zapisany plik wyjściowy (np: C:\folder);

        private void MergeFile(string firstfile, string wheresave)
        {
            try
            {
                FileInfo file = new FileInfo(firstfile);
                DirectoryInfo directory = new DirectoryInfo(file.DirectoryName);
                Stream inputStream;
                Stream localStream;
                string filename = "";
                string localFilename;
                byte[] buffer = new byte[1024];
                int bytesRead;
                Regex theRegex = new Regex(@"(?<filename>((\S|\s|\d)+).((\S|\d)+)).part\d+.fs");
                MatchCollection theMatches = theRegex.Matches(file.Name);
                foreach (Match thematch in theMatches)
                    filename = thematch.Groups["filename"].ToString();
                FileInfo[] files = directory.GetFiles("*.part*.fs");
                int parts = 0;
                foreach (FileInfo x in files)
                    parts++;
                localFilename = wheresave + @"\" + filename;
                localStream = File.Create(localFilename);
                for (int a = 1; a < parts + 1; a++)
                {
                    inputStream = File.OpenRead(directory.FullName + @"\" + filename + ".part" + a + ".fs");
                    do
                    {
                        bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                        localStream.Write(buffer, 0, bytesRead);
                    } while (bytesRead > 0);
                    inputStream.Close();
                }
                localStream.Close();
            }
            catch
            {
                MessageBox.Show("Error!");
                return;
            }
            MessageBox.Show("OK");
        }

Pytanie nr1:
Jak zmodyfikować ten kod, ażeby podczas dzielenia plików zapisana została informacja o liczbie części, hash crc32, jak sprawdzić potem która część jest prawidłowa, a która jednak nie?
Pytanie nr2:
Do czego służy metoda GetHashCode?
Pytanie nr3:
Jak najłatwiej i najbezpieczniej zaszyfrować wiadomość za pomocą C#? (pojedyncze litery, ale także całe wyrazy i zdania (a może i pliki)?)

dzięki za odpowiedź ;-)

0

Może trochę inaczej sformułuje moje pytanie:
Pod spodem znajduje się kod, który koduje stringi i zakodowaną informację zapisuje do pliku oraz rozszyfrowuje go.

string FileName = @"C:\Text.txt";
        Rijndael RijndaelAlg = Rijndael.Create();

        private void button1_Click(object sender, EventArgs e)
        {
            string Final = DecryptTextFromFile(FileName, RijndaelAlg.Key, 

RijndaelAlg.IV);
            MessageBox.Show(Final);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                string sData = "tekst";
                EncryptTextToFile(sData, FileName, RijndaelAlg.Key, RijndaelAlg.IV);
            }
            catch
            {
                MessageBox.Show("Błąd");
            }
        }

        public static void EncryptTextToFile(String Data, String FileName, byte[] Key, 

byte[] IV)
        {
            try
            {
                FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
                Rijndael RijndaelAlg = Rijndael.Create();
                CryptoStream cStream = new CryptoStream(fStream,
                    RijndaelAlg.CreateEncryptor(Key, IV),
                    CryptoStreamMode.Write);
                StreamWriter sWriter = new StreamWriter(cStream);
                sWriter.WriteLine(Data);
                sWriter.Close();
                cStream.Close();
                fStream.Close();
            }
            catch
            {
                MessageBox.Show("Błąd");
            }

        }

        public static string DecryptTextFromFile(String FileName, byte[] Key, byte[] 

IV)
        {
            try
            {
                FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);
                Rijndael RijndaelAlg = Rijndael.Create();
                CryptoStream cStream = new CryptoStream(fStream,
                    RijndaelAlg.CreateDecryptor(Key, IV),
                    CryptoStreamMode.Read);
                StreamReader sReader = new StreamReader(cStream);
                string val = null;
                val = sReader.ReadLine();
                sReader.Close();
                cStream.Close();
                fStream.Close();
                return val;
            }
            catch
            {
                MessageBox.Show("Błąd");
                return null;
            }
        }

Oto moje pytania:
-jak zmienić kod, żeby informacja zakodowana znalazła się w jakiejś zmiennej, a nie została zapisana do pliku?
-dało by się jakoś informację zakodowaną przekształcić jedynie na litery i cyfry?

0

Oto moje pytania:
-jak zmienić kod, żeby informacja zakodowana znalazła się w jakiejś zmiennej, a nie została zapisana do pliku?
-dało by się jakoś informację zakodowaną przekształcić jedynie na litery i cyfry?

Pytanie pierwsze - mozesz uzyc MemoryStream. Nie zapisze sie do pliku, mozesz sobie pomanipulowac i pozniej ewentualnie zapisac zmiany.
Pytanie drugie - nie znam tego algorytmu, ale przykladowo uzywajac hasha MD5 wyniki dostaje sie w bajtach. Zeby zamienic to na przystepna wersje (szesnastkowo) ja uzywam

byte [] vHash = ...//tu funkcja md5
string tekstHasha = "":
for (int i=0; i<vHash.Length(); i++)
 tekstHasha += vHash[i].ToString("x2");

pozdrawiam
johny

0

dzięki, mam do Was jeszcze jedno pytanie:
znalazłem w końvu to o co mi chodziło: bardzo prostą metodę szyfrującą i deszyfrującą.
Jako argumenty podajemy tekst do zaszyfrowania oraz klucz (tekst znaków). Metoda zwraca tekst zaszyfrowany miły dla oka :)

        public string Encrypt(string clearText, string Password)
        {
            byte[] clearBytes =
              System.Text.Encoding.Unicode.GetBytes(clearText);
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
            byte[] encryptedData = Encrypt(clearBytes,
                     pdb.GetBytes(32), pdb.GetBytes(16));
            return Convert.ToBase64String(encryptedData);
        }

Metoda deszyfrująca.
Argumenty: tekst zaszyfrowany, klucz, zwraca odkodowany tekst

        public string Decrypt(string cipherText, string Password)
        {
            byte[] cipherBytes = Convert.FromBase64String(cipherText);
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
            byte[] decryptedData = Decrypt(cipherBytes,
                pdb.GetBytes(32), pdb.GetBytes(16)); 
            return System.Text.Encoding.Unicode.GetString(decryptedData);
        }

Moje pytanie: jak bezpieczny jest ten szyfr (ile bitów musiałby mieć klucz (wystarczy 32?)) oraz jaki to rodzaj szyfru (AES?)
dzięki za odp i za zainteresowanie moim problemem ;-P

0

Jakbys mogl jeszcze podac gdzie znajduje sie ta metoda Encrypt/Decrypt bo nie moge sie za nic domyslec z tego kodu, chyba troche ciezko dzisiaj mysle...

pozdrawiam
johny

0

Metody znalazłem na tej stronie:
http://www.codeproject.com/dotnet/DotNetCrypto.asp
tam także znajdują się inne metody szyfrowania (min plików)

0
Roland napisał(a)

Metody znalazłem na tej stronie:
http://www.codeproject.com/dotnet/DotNetCrypto.asp
tam także znajdują się inne metody szyfrowania (min plików)

Z tego co tam napisano wynika, ze to Rijndael, czyli AES.

A tutaj http://csrc.nist.gov/CryptoToolkit/aes/rijndael/ w specyfikacji pisza, ze:

The most efficient key-recovery attack for
Rijndael is exhaustive key search. Obtaining information from given plaintext-ciphertext pairs
about other plaintext-ciphertext pairs cannot be done more efficiently than by determining the
key by exhaustive key search. The expected effort of exhaustive key search depends on the
length of the Cipher Key and is:
? for a 16-byte key, 2^127 applications of Rijndael;
? for a 24-byte key, 2^191 applications of Rijndael;
? for a 32-byte key, 2^255 applications of Rijndael.

O ile dobrze pamietam dla 3DES'a bylo to 2^112.

pozdrawiam
johny

1 użytkowników online, w tym zalogowanych: 0, gości: 1