El petit hashejador que va creixer ha crescut un xic més. Ara ja incorpora xifrat.
I clar, el xifrat ha de ser simètric per anar ràpid. El 3DES ja l'estan treient de circulació, encara no està retirat però ja es considera un xifrat dèbil. El que s'està aplicant ara és el AES, encara que l'AES és del 1998 i el 3DES del 1995... gaire moderns no són.
Així que dit i fet ara he afegit les opcions de xifrat:
- "obre" desxifra una carpeta, elimina els fitxers xifrats i deixa els normals.
- "tanca" xifra una carpeta, elimina els fitxers normals i deixa els xifrats.
- "-pxxxx" i a continuació la contrasenya feta servir per xifrar o desxifrar.
- "[-f]" force, salta les precaucions: No xifrar dos cops, verificar la contrasenya.
- "[-r]" Recursiu, per aplicar la mateixa operació a les subcarpetes.
- "-cnom_carpeta" nom de la carpeta a processar. Si no informat es fa servir carpeta executable.
- "neteja" esborra el fitxer locker.xml, amb opcio [-r]
- "crea -cnom_carpeta [-r] [-desde_cero]" crea un fitxer XML amb els Hash dels fitxers. -r indica recursiu. -desde_cero: esborra els fitxers de hashos existents.
- "verifica -cnom_carpeta [-r] [-continua]" verifica que els fitxers tinguin el Hash correcte, -r indica recursiu, -continua no verifica els fitxers en estat VERIFICAT
- "resultats -cnom_carpeta [-r]" no calcula hashos, llegeix els fitxers del hasher buscant fitxers amb modificacions, -r indica recursiu
- "actualitza -cpath [-r]" calcula hashos per fitxers nous, esborra del fitxer de hashos els que pertanyen a fitxers esborrats, -r indica recursiu
- "reset -cpath [-r]" reseteja l'estat a PENDENT, -r indica recursiu
- "crea_tanca" realitza dues accions seguides.
- "verifica_tanca" realitza dues accions seguides.
- "obre_verifica" realitza dues accions seguides.
- El fitxer locker.xml conté informació sobre el tancat.
- El fitxer hasher.xml conté informació sobre els hashos, l'estat del fitxer i la data que es va fer.
Com sempre el codi a continuació:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace OpenSesame
{
class Program
{
private static string ExecutablePath = "";
private static string Accio = "";
private static bool Recursiu = false;
private static bool Force = false;
private static string Pwd = "";
private static string CarpetaAProcessar = "";
private static bool Creacio_de_cero = false;
private static bool Continua = false;
static void Main(string[] args)
{
string AppPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
ExecutablePath = Path.GetDirectoryName(AppPath);
clsDadesDesxifratRetorn ResultatsDesxifrar = null;
clsDadesVerificacioRetorn ResultatsVerificacio = null;
clsDadesXifratRetorn ResultatsXifrat = null;
try
{
ParseParams(args);
if (string.IsNullOrWhiteSpace(CarpetaAProcessar)) CarpetaAProcessar = ExecutablePath;
switch (Accio)
{
case "obre":
if (string.IsNullOrWhiteSpace(Pwd))
{
Console.WriteLine("Password no informada");
return;
}
ResultatsDesxifrar = obre(CarpetaAProcessar);
Console.WriteLine(ResultatsDesxifrar.AString());
break;
case "tanca":
if (string.IsNullOrWhiteSpace(Pwd))
{
Console.WriteLine("Password no informada");
return;
}
ResultatsXifrat = tanca(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - xifrat acabat.");
Console.WriteLine(ResultatsXifrat.AString());
break;
case "neteja":
Neteja(CarpetaAProcessar);
break;
case "crea":
crea(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - creació acabada.");
break;
case "verifica":
ResultatsVerificacio = verifica(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - verificació acabada.");
Console.WriteLine(ResultatsVerificacio.AString());
break;
case "resultats":
ResultatsVerificacio = resultats(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - resultats acabat");
Console.WriteLine(ResultatsVerificacio.AString());
break;
case "actualitza":
actualitza(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - actualitza acabat.");
break;
case "reset":
reset(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - reset acabat.");
break;
case "crea_tanca":
crea(CarpetaAProcessar);
ResultatsXifrat = tanca(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - crea_tanca acabat.");
Console.WriteLine(ResultatsXifrat.AString());
break;
case "verifica_tanca":
ResultatsVerificacio = verifica(CarpetaAProcessar);
if (ResultatsVerificacio.FitxersHashDiferent == 0)
{
ResultatsXifrat = tanca(CarpetaAProcessar);
}
else
{
Console.WriteLine(ObtenirData() + " - xifrat no efectuat, hi ha fitxers amb hashs diferents dels esperats.");
Console.WriteLine("Actualitzar els hashos o fer servir l'opció \"tanca\" de forma individual");
ResultatsXifrat = new clsDadesXifratRetorn();
}
Console.WriteLine(ObtenirData() + " - resultats verificació:");
Console.Write(ResultatsVerificacio.AString());
Console.WriteLine(ObtenirData() + " - resultats xifrat:");
Console.Write(ResultatsXifrat.AString());
break;
case "obre_verifica":
ResultatsDesxifrar = obre(CarpetaAProcessar);
ResultatsVerificacio = verifica(CarpetaAProcessar);
Console.WriteLine(ObtenirData() + " - resultats desxifrar:");
Console.Write(ResultatsDesxifrar.AString());
Console.WriteLine(ObtenirData() + " - resultats verificació:");
Console.Write(ResultatsVerificacio.AString());
break;
default:
Console.WriteLine("Possibles accions:");
Console.WriteLine("\"obre\" desxifra una carpeta, elimina els fitxers xifrats i deixa els normals.");
Console.WriteLine("\"tanca\" xifra una carpeta, elimina els fitxers normals i deixa els xifrats.");
Console.WriteLine("\"-pxxxx\" i a continuació la contrasenya feta servir per xifrar o desxifrar.");
Console.WriteLine("[-f] force, salta les precaucions: No xifrar dos cops, verificar la contrasenya.");
Console.WriteLine("[-r] Recursiu, per aplicar la mateixa operació a les subcarpetes.");
Console.WriteLine("\"-cnom_carpeta\" nom de la carpeta a processar. Si no informat es fa servir carpeta executable.");
Console.WriteLine("\"neteja\" esborra el fitxer hasher.xml i locker.xml, amb opcio [-r]");
Console.WriteLine("\"crea -cnom_carpeta [-r] [-desde_cero]\" crea un fitxer XML amb els Hash dels fitxers. -r indica recursiu. -desde_cero: esborra els fitxers de hashos existents.");
Console.WriteLine("\"verifica -cnom_carpeta [-r] [-continua]\" verifica que els fitxers tinguin el Hash correcte, -r indica recursiu, -continua no verifica els fitxers en estat VERIFICAT");
Console.WriteLine("\"resultats -cnom_carpeta [-r]\" no calcula hashos, llegeix els fitxers del hasher buscant fitxers amb modificacions, -r indica recursiu");
Console.WriteLine("\"actualitza -cpath [-r]\" calcula hashos per fitxers nous, esborra del fitxer de hashos els que pertanyen a fitxers esborrats, -r indica recursiu");
Console.WriteLine("\"reset -cpath [-r]\" reseteja l'estat a PENDENT, -r indica recursiu");
Console.WriteLine("\"crea_tanca\" realitza dues accions seguides.");
Console.WriteLine("\"verifica_tanca\" realitza dues accions seguides.");
Console.WriteLine("\"obre_verifica\" realitza dues accions seguides.");
Console.WriteLine("El fitxer locker.xml conté informació sobre el tancat.");
Console.WriteLine("El fitxer hasher.xml conté informació sobre els hashos, l'estat del fitxer i la data que es va fer.");
break;
}
Console.WriteLine("OpenSesame 1.0 - 03-03-2020");
}
catch(Exception Err)
{
Console.WriteLine(Err.Message);
}
}
private static void reset(string pPath)
{
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
Console.WriteLine(ObtenirData() + " - resetejant: " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
objFitxer.Value.Estat = "PENDENT";
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
reset(Carpeta);
}
}
}
private static void Neteja(string pPath)
{
if (!Directory.Exists(pPath))
{
Console.WriteLine("Carpeta no trobada: " + pPath);
}
else
{
if (File.Exists(pPath + "\\locker.xml"))
{
File.Delete(pPath + "\\locker.xml");
}
if (File.Exists(pPath + "\\hasher.xml"))
{
File.Delete(pPath + "\\hasher.xml");
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
Neteja(Carpeta);
}
}
}
}
private static void ParseParams(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i].ToLower() == "obre")
{
Accio = "obre";
}
if (args[i].ToLower() == "tanca")
{
Accio = "tanca";
}
if (args[i].ToLower() == "neteja")
{
Accio = "neteja";
}
if (args[i].ToLower().StartsWith("-p"))
{
Pwd = args[i].Replace("-p", "");
}
if (args[i].ToLower() == "crea")
{
Accio = "crea";
}
if (args[i].ToLower() == "verifica")
{
Accio = "verifica";
}
if (args[i].ToLower() == "resultats")
{
Accio = "resultats";
}
if (args[i].ToLower() == "actualitza")
{
Accio = "actualitza";
}
if (args[i].ToLower() == "reset")
{
Accio = "reset";
}
if (args[i].ToLower() == "crea_tanca")
{
Accio = "crea_tanca";
}
if (args[i].ToLower() == "verifica_tanca")
{
Accio = "verifica_tanca";
}
if (args[i].ToLower() == "obre_verifica")
{
Accio = "obre_verifica";
}
if (args[i].ToLower() == "-r")
{
Recursiu = true;
}
if (args[i].ToLower() == "-desde_cero")
{
Creacio_de_cero = true;
}
if (args[i].ToLower() == "-continua")
{
Continua = true;
}
if (args[i].ToLower() == "-f")
{
Force = true;
}
if (args[i].Contains(":") && args[i].Contains("-c"))
{
CarpetaAProcessar = args[i].Replace("\\\\", "\\").Replace("-c", "").Trim();
}
}
}
private static byte[] PwdBytes(string pPwd)
{
SHA256Managed SHA2 = new SHA256Managed();
UTF8Encoding encoder = new UTF8Encoding();
byte[] bodyStringBytes = encoder.GetBytes(pPwd);
byte[] pwdBytes = SHA2.ComputeHash(bodyStringBytes);
return pwdBytes;
}
private static byte[] IVBytes(string pPwd, string FileName)
{
SHA256Managed SHA2 = new SHA256Managed();
UTF8Encoding encoder = new UTF8Encoding();
byte[] bodyStringBytes = encoder.GetBytes(pPwd + FileName);
byte[] IV = new byte[16];
byte[] Hash = SHA2.ComputeHash(bodyStringBytes);
int i, j;
i = 0;
j = 0;
while (i < 32)
{
IV[j] = Hash[i];
i = i + 2;
j++;
}
return IV;
}
private static clsDadesDesxifratRetorn obre(string pPath)
{
string[] Fitxers = Directory.GetFiles(pPath, "*.xxx");
byte[] passwordBytes = PwdBytes(Pwd);
clsConfig Config = new clsConfig();
string KCVPwd = CalcularKCV();
string KCVFitxer = "";
bool ErrorDesxifrant = false;
clsDadesDesxifratRetorn Retorn = new clsDadesDesxifratRetorn();
if (!Directory.Exists(pPath))
{
Console.WriteLine("Carpeta no trobada: " + pPath);
return Retorn;
}
DirectoryInfo DInfo = new DirectoryInfo(pPath);
if (DInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
Console.WriteLine(ObtenirData() + " - carpeta oculta no processada: " + pPath);
return Retorn;
}
Config.Initialize(pPath);
if (Config.bError && !Force)
{
Console.WriteLine(ObtenirData() + " - Sense config: " + Config.txtError + ". Fer servir opció -f (force).");
Retorn.CarpetesSenseFitxerConfiguracio++;
}
else
{
if (Config.GetVal("Estat") == "tancat" || Force )
{
KCVFitxer = Config.GetVal("ValidadorClau");
if (KCVFitxer == KCVPwd || Force)
{
if (Fitxers.Length != 0)
{
foreach (string Fitxer in Fitxers)
{
if (PotProcessarFitxer(Fitxer))
{
FileInfo FInfo = new FileInfo(Fitxer);
ErrorDesxifrant = false;
try
{
DeCryptFile(Fitxer, passwordBytes, FInfo.Length);
Console.WriteLine(ObtenirData() + " - DeCrypted OK: " + Path.GetFileName(Fitxer));
Retorn.FitxersDesxifratsOK++;
}
catch(Exception Err)
{
Console.WriteLine(ObtenirData() + " - Error desxifrant: " + Fitxer);
Console.WriteLine(Err.Message);
Retorn.FitxersDesxifratsKO++;
ErrorDesxifrant = true;
}
try
{
if (!ErrorDesxifrant)
{
File.Delete(Fitxer);
Retorn.FitxersEsborratsOK++;
}
}
catch (Exception Err)
{
Console.WriteLine(ObtenirData() + " - Error esborrant fitxer: " + Path.GetFileName(Fitxer) + ", " + Err.Message);
Retorn.FitxersEsborratsKO++;
}
}
}
}
else
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxers a obrir: " + pPath);
Retorn.CarpetesSenseFitxers++;
}
Config.SetVal("Estat", "obert");
Config.SetVal("Data", DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
Config.Save(pPath);
}
else
{
Console.WriteLine(ObtenirData() + " - Password incorrecte: " + pPath);
Retorn.CarpetesPwdIncorrecte++;
}
}
else
{
Console.WriteLine(ObtenirData() + " - La carpeta ja està oberta: " + pPath);
Retorn.CarpetesJaDesxifrades++;
}
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
clsDadesDesxifratRetorn RetornRecusiu;
foreach (string Carpeta in Carpetes)
{
RetornRecusiu = obre(Carpeta);
Retorn.CarpetesJaDesxifrades = Retorn.CarpetesJaDesxifrades + RetornRecusiu.CarpetesJaDesxifrades;
Retorn.CarpetesPwdIncorrecte = Retorn.CarpetesPwdIncorrecte + RetornRecusiu.CarpetesPwdIncorrecte;
Retorn.CarpetesSenseFitxerConfiguracio = Retorn.CarpetesSenseFitxerConfiguracio + RetornRecusiu.CarpetesSenseFitxerConfiguracio;
Retorn.CarpetesSenseFitxers = Retorn.CarpetesSenseFitxers + RetornRecusiu.CarpetesSenseFitxers;
Retorn.FitxersDesxifratsKO = Retorn.FitxersDesxifratsKO + RetornRecusiu.FitxersDesxifratsKO;
Retorn.FitxersDesxifratsOK = Retorn.FitxersDesxifratsOK + RetornRecusiu.FitxersDesxifratsOK;
Retorn.FitxersEsborratsKO = Retorn.FitxersEsborratsKO + RetornRecusiu.FitxersEsborratsKO;
Retorn.FitxersEsborratsOK = Retorn.FitxersEsborratsOK + RetornRecusiu.FitxersEsborratsOK;
}
}
return Retorn;
}
private static clsDadesXifratRetorn tanca(string pPath)
{
clsDadesXifratRetorn Retorn = new clsDadesXifratRetorn();
string[] Fitxers = Directory.GetFiles(pPath);
byte[] passwordBytes = PwdBytes(Pwd);
bool ErrorXifrant = false;
clsConfig Config = new clsConfig();
long TamanyFitxer = 0;
if (!Directory.Exists(pPath))
{
Console.WriteLine("Carpeta no trobada: " + pPath);
return Retorn;
}
DirectoryInfo DInfo = new DirectoryInfo(pPath);
if (DInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
Console.WriteLine(ObtenirData() + " - carpeta oculta no processada: " + pPath);
return Retorn;
}
if (File.Exists(pPath + "\\locker.xml"))
{
Config.Initialize(pPath);
}
else
{
Retorn.CarpetesSenseFitxerConfiguracio++;
Console.WriteLine(ObtenirData() + " - carpeta sense fitxer de configuració.");
}
if(Config.GetVal("Estat") == "tancat")
{
Retorn.CarpetesJaXifrades++;
Console.WriteLine(ObtenirData() + " - carpeta ja tancada, si vols tancar-la altra cop, esborra el fitxer locker.xml");
return Retorn;
}
Config.SetVal("ValidadorClau", CalcularKCV());
Config.SetVal("Estat", "tancat");
Config.SetVal("Data", DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
foreach (string Fitxer in Fitxers)
{
if (PotProcessarFitxer(Fitxer.ToLower()))
{
ErrorXifrant = false;
FileInfo FInfo = new FileInfo(Fitxer);
if (FInfo.IsReadOnly)
{
Retorn.FitxersReadonly++;
Console.WriteLine(ObtenirData() + " - fitxer readonly no xifrat: " + Path.GetFileName(Fitxer));
}
else
{
TamanyFitxer = FInfo.Length;
if (TamanyFitxer == 0)
{
Retorn.FitxersTamany0++;
Console.WriteLine(ObtenirData() + " - fitxer tamany 0 no xifrat: " + Path.GetFileName(Fitxer));
}
else
{
if (FInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
Retorn.FitxersOcults++;
Console.WriteLine(ObtenirData() + " - fitxer ocult no xifrat: " + Path.GetFileName(Fitxer));
}
else
{
try
{
CryptFile(Fitxer, passwordBytes, TamanyFitxer);
Retorn.FitxersXifratsOK++;
}
catch (Exception Err)
{
ErrorXifrant = true;
Console.WriteLine(ObtenirData() + " - error xifrant fitxer: " + Path.GetFileName(Fitxer) + ": " + Err.Message);
Retorn.FitxersXifratsKO++;
}
try
{
if (!ErrorXifrant)
{
File.Delete(Fitxer);
Retorn.FitxersEsborratsOK++;
}
}
catch (Exception Err)
{
Retorn.FitxersEsborratsKO++;
Console.WriteLine(ObtenirData() + " - error esborrant fitxer: " + Path.GetFileName(Fitxer) + ", " + Err.Message);
}
}
}
}
}
}
Config.Save(pPath);
if (Recursiu)
{
clsDadesXifratRetorn RetornRecursiu = null;
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
RetornRecursiu = tanca(Carpeta);
Retorn.CarpetesJaXifrades = Retorn.CarpetesJaXifrades + RetornRecursiu.CarpetesJaXifrades;
Retorn.CarpetesSenseFitxerConfiguracio = Retorn.CarpetesSenseFitxerConfiguracio + RetornRecursiu.CarpetesSenseFitxerConfiguracio;
Retorn.FitxersEsborratsKO = Retorn.FitxersEsborratsKO + RetornRecursiu.FitxersEsborratsKO;
Retorn.FitxersEsborratsOK = Retorn.FitxersEsborratsOK + RetornRecursiu.FitxersEsborratsOK;
Retorn.FitxersOcults = Retorn.FitxersOcults + RetornRecursiu.FitxersOcults;
Retorn.FitxersReadonly = Retorn.FitxersReadonly + RetornRecursiu.FitxersReadonly;
Retorn.FitxersTamany0 = Retorn.FitxersTamany0 + RetornRecursiu.FitxersTamany0;
Retorn.FitxersXifratsKO = Retorn.FitxersXifratsKO + RetornRecursiu.FitxersXifratsKO;
Retorn.FitxersXifratsOK = Retorn.FitxersXifratsOK + RetornRecursiu.FitxersXifratsOK;
}
}
return Retorn;
}
private static bool PotProcessarFitxer(string Fitxer)
{
string NomEnMinuscules = Fitxer.ToLower();
if (!NomEnMinuscules.Contains("opensesame.exe")
&& !NomEnMinuscules.Contains("hasher.xml")
&& !NomEnMinuscules.Contains("hasher.exe")
&& !NomEnMinuscules.Contains("locker.xml"))
{
return true;
}
else
{
return false;
}
}
private static void CryptFile(string inputFile, byte[] passwordBytes, long TamanyFitxer)
{
FileStream fsCrypt = new FileStream(inputFile + ".xxx", FileMode.Create);
string NomFitxerSenseRutaNiUnitat = Path.GetFileName(inputFile);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
AES.Padding = PaddingMode.PKCS7;
AES.Key = passwordBytes;
NomFitxerSenseRutaNiUnitat = NomFitxerSenseRutaNiUnitat.ToLower();
AES.IV = IVBytes(Pwd, NomFitxerSenseRutaNiUnitat);
AES.FeedbackSize = 128;
AES.Mode = CipherMode.CFB;
CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
byte[] buffer = new byte[4194304];
int read;
if (TamanyFitxer < 4194304)
{
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
cs.Write(buffer, 0, read);
}
Console.WriteLine(ObtenirData() + " - crypted OK: " + Path.GetFileName(inputFile));
}
else
{
double Percentatge = 0;
string strPercentatge = "";
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
Percentatge = (double) fsIn.Position / TamanyFitxer;
Percentatge = Percentatge * 100;
Percentatge = Math.Round(Percentatge, 2);
strPercentatge = String.Format("{0:00.00}", Percentatge);
Console.Write("\r" + ObtenirData(DateTime.Now) + " - crypted " + strPercentatge + "% " + Path.GetFileName(inputFile));
cs.Write(buffer, 0, read);
}
Console.WriteLine();
}
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
private static void DeCryptFile(string inputFile, byte[] passwordBytes, long TamanyFitxer)
{
string NomFitxerSenseRutaNiUnitat = Path.GetFileName(inputFile);
NomFitxerSenseRutaNiUnitat = NomFitxerSenseRutaNiUnitat.Replace(".xxx", "");
NomFitxerSenseRutaNiUnitat = NomFitxerSenseRutaNiUnitat.ToLower();
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
AES.FeedbackSize = 128;
AES.Key = passwordBytes;
AES.IV = IVBytes(Pwd, NomFitxerSenseRutaNiUnitat);
AES.Padding = PaddingMode.PKCS7;
AES.Mode = CipherMode.CFB;
CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);
FileStream fsOut = new FileStream(inputFile.Replace(".xxx", ""), FileMode.Create);
int read;
byte[] buffer = new byte[4194304];
if (TamanyFitxer < 4194304)
{
while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
{
fsOut.Write(buffer, 0, read);
}
}
else
{
long Posicio = 0;
double Percentatge = 0;
string strPercentatge = "";
while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
{
Posicio = Posicio + read;
Percentatge = (double) Posicio / TamanyFitxer;
Percentatge = Percentatge * 100;
Percentatge = Math.Round(Percentatge, 2);
strPercentatge = String.Format("{0:00.00}", Percentatge);
Console.Write("\r" + ObtenirData(DateTime.Now) + " - Decrypted " + strPercentatge + "% " + Path.GetFileName(inputFile));
fsOut.Write(buffer, 0, read);
}
Console.WriteLine();
}
cs.Close();
fsOut.Close();
fsCrypt.Close();
}
private static string CalcularKCV()
{
try
{
AesCryptoServiceProvider AES = new AesCryptoServiceProvider();
#region definicio de variables
string strIVAES = "00000000000000000000000000000000";
byte[] IV = ConvertHexStringToByteArray(strIVAES);
byte[] OrigenBytes = null;
byte[] Encrypted = null;
byte[] KCV = new byte[3];
ICryptoTransform EncDec = null;
#endregion
AES.KeySize = 256;
AES.Key = PwdBytes(Pwd);
AES.IV = IV;
AES.Mode = CipherMode.ECB;
AES.Padding = PaddingMode.Zeros;
OrigenBytes = ConvertHexStringToByteArray("00000000000000000000000000000000");
Encrypted = new byte[OrigenBytes.Length];
EncDec = AES.CreateEncryptor();
EncDec.TransformBlock(OrigenBytes, 0, 16, Encrypted, 0);
KCV[0] = Encrypted[0];
KCV[1] = Encrypted[1];
KCV[2] = Encrypted[2];
return ConvertByteArrayToHexString(KCV);
}
catch (Exception E)
{
Console.WriteLine(E.Message);
return "ERROR";
}
}
public static string ConvertByteArrayToHexString(byte[] ba)
{
StringBuilder sb = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString().ToUpper();
}
public static byte[] SubArray(byte[] data, int index, int length)
{
byte[] result = new byte[length];
Array.Copy(data, index, result, 0, length);
return result;
}
public static byte[] ConvertHexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
{
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Los datos de entrada tiene un número impar de caracteres, no se puede convertir a Hexadecimal: {0}", hexString.Length));
}
byte[] HexAsBytes = new byte[hexString.Length / 2];
for (int index = 0; index < HexAsBytes.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return HexAsBytes;
}
public static string ObtenirData()
{
return DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static string ObtenirData(DateTime data)
{
return data.ToString("dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
public static string SHA256HashFile(string sPath)
{
string sHash = "";
using (var stream = new BufferedStream(File.OpenRead(sPath), 2400000))
{
SHA256CryptoServiceProvider sha256h = new SHA256CryptoServiceProvider();
sHash = BitConverter.ToString(sha256h.ComputeHash(stream));
}
return sHash;
}
private static void actualitza(string pPath)
{
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
clsConfig Config = new clsConfig();
if (File.Exists(pPath + "\\locker.xml"))
{
Config.Initialize(pPath);
if (Config.GetVal("Estat") == "tancat")
{
Console.WriteLine("Carpeta xifrada, no es poden calcular els hashs dels fitxers");
return;
}
}
Dictionary<string, clsFitxer> DicFitxers;
Dictionary<string, clsFitxer> FitxersActualitzats = new Dictionary<string, clsFitxer>();
clsFitxer FitxerActualitzat = null;
DicFitxers = CarregaHashos(pPath);
DirectoryInfo dir = new DirectoryInfo(pPath);
FileInfo[] Fitxers = dir.GetFiles();
Console.WriteLine(ObtenirData() + " - Processant " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
try
{
if (File.Exists(pPath + "\\" + objFitxer.Value.Nom))
{
FitxerActualitzat = new clsFitxer(objFitxer.Value.Nom, objFitxer.Value.DataCreacio, objFitxer.Value.DataVerificacio, objFitxer.Value.MidaEnBytes, objFitxer.Value.Hash, objFitxer.Value.Estat);
FitxersActualitzats.Add(FitxerActualitzat.Nom, FitxerActualitzat);
}
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
foreach (FileInfo Fitxer in Fitxers)
{
if (!DicFitxers.ContainsKey(Fitxer.Name))
{
if (PotProcessarFitxer(Fitxer.Name))
{
string hashValueStr = SHA256HashFile(Fitxer.FullName);
Console.WriteLine(ObtenirData() + " - hashejat: " + Fitxer.Name);
FitxerActualitzat = new clsFitxer(Fitxer.Name, DateTime.Now, DateTime.Now, Fitxer.Length, hashValueStr, "CREAT");
FitxersActualitzats.Add(Fitxer.Name, FitxerActualitzat);
}
}
}
Save(pPath, FitxersActualitzats);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
actualitza(Carpeta);
}
}
}
public static void crea(string pPath)
{
bool Procesa_carpeta = false;
if (File.Exists(pPath + "\\hasher.xml"))
{
if (Creacio_de_cero)
{
File.Delete(pPath + "\\hasher.xml");
Console.WriteLine(ObtenirData() + " - Carpeta " + pPath + " amb fitxer de hashos, esborrat.");
Procesa_carpeta = true;
}
else
{
Console.WriteLine(ObtenirData() + " - Carpeta " + pPath + " amb fitxer de hashos, no procesada.");
Procesa_carpeta = false;
}
}
else
{
Procesa_carpeta = true;
}
if (Procesa_carpeta)
{
Console.WriteLine(ObtenirData() + " - creant fitxer hashos: " + pPath);
DirectoryInfo dir = new DirectoryInfo(pPath);
FileInfo[] files = dir.GetFiles();
clsFitxer objFitxer = null;
Dictionary<string, clsFitxer> DicFitxers = new Dictionary<string, clsFitxer>();
foreach (FileInfo Fitxer in files)
{
try
{
if (PotProcessarFitxer(Fitxer.Name))
{
string hashValueStr = SHA256HashFile(Fitxer.FullName);
Console.WriteLine(ObtenirData() + " - hashejat: " + Fitxer.Name);
objFitxer = new clsFitxer(Fitxer.Name, DateTime.Now, DateTime.Now, Fitxer.Length, hashValueStr, "CREAT");
DicFitxers.Add(Fitxer.Name, objFitxer);
}
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
crea(Carpeta);
}
}
}
public static void Save(string pPath, Dictionary<string, clsFitxer> DicFitxers)
{
XmlDocument Doc = new XmlDocument();
XmlNode Fitxers;
XmlNode Fitxer;
XmlNode Nom;
XmlNode Hash;
XmlNode DataCreacio;
XmlNode DataVerificacio;
XmlNode Estat;
XmlNode MidaEnBytes;
Doc.LoadXml("<?xml version=\"1.0\" standalone=\"yes\"?><fitxers></fitxers>");
Fitxers = Doc.SelectSingleNode("descendant::fitxers");
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
Fitxer = Doc.CreateNode(XmlNodeType.Element, "fitxer", "");
Nom = Doc.CreateNode(XmlNodeType.Element, "nom", "");
Hash = Doc.CreateNode(XmlNodeType.Element, "hash", "");
DataCreacio = Doc.CreateNode(XmlNodeType.Element, "datacreacio", "");
DataVerificacio = Doc.CreateNode(XmlNodeType.Element, "dataverificacio", "");
Estat = Doc.CreateNode(XmlNodeType.Element, "estat", "");
MidaEnBytes = Doc.CreateNode(XmlNodeType.Element, "midaenbytes", "");
Nom.InnerText = objFitxer.Value.Nom;
Hash.InnerText = objFitxer.Value.Hash;
DataCreacio.InnerText = ObtenirData(objFitxer.Value.DataCreacio);
DataVerificacio.InnerText = ObtenirData(objFitxer.Value.DataVerificacio);
Estat.InnerText = objFitxer.Value.Estat;
MidaEnBytes.InnerText = objFitxer.Value.MidaEnBytes.ToString();
Fitxer.AppendChild(Nom);
Fitxer.AppendChild(Hash);
Fitxer.AppendChild(DataCreacio);
Fitxer.AppendChild(DataVerificacio);
Fitxer.AppendChild(Estat);
Fitxer.AppendChild(MidaEnBytes);
Fitxers.AppendChild(Fitxer);
}
Doc.Save(pPath + "\\hasher.xml");
}
public static clsDadesVerificacioRetorn verifica(string pPath)
{
clsDadesVerificacioRetorn Retorn = new clsDadesVerificacioRetorn();
long GBHashejats = 0;
Console.WriteLine(ObtenirData() + " - verificant carpeta: " + pPath);
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
clsConfig Config = new clsConfig();
if (File.Exists(pPath + "\\locker.xml"))
{
Config.Initialize(pPath);
if (Config.GetVal("Estat") == "tancat")
{
Console.WriteLine(ObtenirData() + " - Carpeta xifrada, no es poden verificar els hashs dels fitxers");
return Retorn;
}
}
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
if (objFitxer.Value.Estat == "VERIFICAT" && Continua)
{
Console.WriteLine(ObtenirData() + " - fitxer ja verificat anteriorment: " + objFitxer.Value.Nom);
}
else
{
try
{
if (File.Exists(pPath + "\\" + objFitxer.Value.Nom))
{
FileInfo fiFitxer = new FileInfo(pPath + "\\" + objFitxer.Value.Nom);
if (fiFitxer.Length != objFitxer.Value.MidaEnBytes)
{
Retorn.FitxersMidaDiferent++;
Console.WriteLine(ObtenirData() + " - Fitxer amb mida diferent: " + fiFitxer.Name);
objFitxer.Value.Estat = "MIDA DIFERENT, actual: " + fiFitxer.Length;
}
else
{
GBHashejats += fiFitxer.Length;
string hashValueStr = SHA256HashFile(fiFitxer.FullName);
if (hashValueStr == objFitxer.Value.Hash)
{
Retorn.FitxersVerificats++;
Console.WriteLine(ObtenirData() + " - Fitxer verificat OK: " + fiFitxer.Name);
objFitxer.Value.Estat = "VERIFICAT";
}
else
{
Retorn.FitxersHashDiferent++;
Console.WriteLine(ObtenirData() + " - Fitxer amb hash canviat: " + fiFitxer.Name);
objFitxer.Value.Estat = "NO COINCIDEIX";
}
if (GBHashejats > 5368709120)
{
GBHashejats = 0;
Save(pPath, DicFitxers);
}
}
}
else
{
Retorn.FitxersEsborrats++;
Console.WriteLine(ObtenirData() + " - Fitxer esborrat: " + objFitxer.Value.Nom);
objFitxer.Value.Estat = "ESBORRAT";
}
objFitxer.Value.DataVerificacio = DateTime.Now;
}
catch (IOException e)
{
Console.WriteLine("I/O Exception: " + e.Message);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("Access Exception: " + e.Message);
}
}
}
Save(pPath, DicFitxers);
}
if (Recursiu)
{
clsDadesVerificacioRetorn RetornRecursiu;
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
RetornRecursiu = verifica(Carpeta);
Retorn.FitxersVerificats = Retorn.FitxersVerificats + RetornRecursiu.FitxersVerificats;
Retorn.FitxersHashDiferent = Retorn.FitxersHashDiferent + RetornRecursiu.FitxersHashDiferent;
Retorn.FitxersMidaDiferent = Retorn.FitxersMidaDiferent + RetornRecursiu.FitxersMidaDiferent;
Retorn.FitxersEsborrats = Retorn.FitxersEsborrats + RetornRecursiu.FitxersEsborrats;
}
}
return Retorn;
}
private static clsDadesVerificacioRetorn resultats(string pPath)
{
clsDadesVerificacioRetorn Retorn = new clsDadesVerificacioRetorn();
if (!File.Exists(pPath + "\\hasher.xml"))
{
Console.WriteLine(ObtenirData() + " - No hi ha fitxer de hashos: " + pPath);
}
else
{
Dictionary<string, clsFitxer> DicFitxers;
DicFitxers = CarregaHashos(pPath);
Console.WriteLine(ObtenirData() + " - analitzant: " + pPath);
foreach (KeyValuePair<String, clsFitxer> objFitxer in DicFitxers)
{
Retorn.FitxersVerificats++;
if (objFitxer.Value.Estat == "NO COINCIDEIX")
{
Retorn.FitxersHashDiferent++;
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio) + " - fitxer amb hash canviat: " + pPath + "\\" + objFitxer.Value.Nom);
}
else
{
if (objFitxer.Value.Estat.Contains("MIDA DIFERENT"))
{
Retorn.FitxersMidaDiferent++;
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio) + " - fitxer amb mida diferent: " + pPath + "\\" + objFitxer.Value.Nom);
}
else
{
if (objFitxer.Value.Estat == "ESBORRAT")
{
Retorn.FitxersEsborrats++;
Console.WriteLine(ObtenirData(objFitxer.Value.DataVerificacio) + " - fitxer esborrat: " + pPath + "\\" + objFitxer.Value.Nom);
}
}
}
}
}
if (Recursiu)
{
clsDadesVerificacioRetorn RetornRecursiu;
string[] Carpetes = Directory.GetDirectories(pPath);
foreach (string Carpeta in Carpetes)
{
RetornRecursiu = resultats(Carpeta);
Retorn.FitxersVerificats = Retorn.FitxersVerificats + RetornRecursiu.FitxersVerificats;
Retorn.FitxersHashDiferent = Retorn.FitxersHashDiferent + RetornRecursiu.FitxersHashDiferent;
Retorn.FitxersMidaDiferent = Retorn.FitxersMidaDiferent + RetornRecursiu.FitxersMidaDiferent;
Retorn.FitxersEsborrats = Retorn.FitxersEsborrats + RetornRecursiu.FitxersEsborrats;
}
}
return Retorn;
}
public static Dictionary<string, clsFitxer> CarregaHashos(string pPath)
{
XmlDocument Doc = new XmlDocument();
XmlNode Fitxers;
XmlNodeList llistaDeFitxer;
XmlNode Nom;
XmlNode Hash;
XmlNode DataCreacio;
XmlNode DataVerificacio;
XmlNode Estat;
XmlNode MidaEnBytes;
clsFitxer objFitxer = null;
Dictionary<string, clsFitxer> DicFitxers = new Dictionary<string, clsFitxer>();
Doc.Load(pPath + "\\hasher.xml");
Fitxers = Doc.SelectSingleNode("descendant::fitxers");
llistaDeFitxer = Fitxers.ChildNodes;
foreach (XmlNode Fitxer in llistaDeFitxer)
{
objFitxer = new clsFitxer();
Nom = Fitxer.SelectSingleNode("descendant::nom");
Hash = Fitxer.SelectSingleNode("descendant::hash");
DataCreacio = Fitxer.SelectSingleNode("descendant::datacreacio");
DataVerificacio = Fitxer.SelectSingleNode("descendant::dataverificacio");
Estat = Fitxer.SelectSingleNode("descendant::estat");
MidaEnBytes = Fitxer.SelectSingleNode("descendant::midaenbytes");
if (Nom != null)
{
objFitxer.Nom = Nom.InnerText;
}
else
{
objFitxer.Nom = "Nom null";
}
if (Hash != null)
{
objFitxer.Hash = Hash.InnerText;
}
else
{
objFitxer.Hash = "Hash null";
}
if (DataCreacio != null)
{
objFitxer.DataCreacio = DateTime.ParseExact(DataCreacio.InnerText, "dd/MM/yyyy HH:mm:ss", null);
}
else
{
objFitxer.DataCreacio = DateTime.Now;
}
if(DataVerificacio != null)
{
objFitxer.DataVerificacio = DateTime.ParseExact(DataVerificacio.InnerText, "dd/MM/yyyy HH:mm:ss", null);
}
else
{
objFitxer.DataVerificacio = DateTime.Now;
}
if(Estat != null)
{
objFitxer.Estat = Estat.InnerText;
}
else
{
objFitxer.Estat = "Estat null";
}
if(MidaEnBytes != null)
{
objFitxer.MidaEnBytes = long.Parse(MidaEnBytes.InnerText);
}
else
{
objFitxer.MidaEnBytes = 0;
}
DicFitxers.Add(objFitxer.Nom, objFitxer);
}
return DicFitxers;
}
}
}
I classes de retorn que es dediquen a recollir estadístiques:
class clsDadesDesxifratRetorn
{
public int FitxersDesxifratsOK = 0;
public int FitxersDesxifratsKO = 0;
public int FitxersEsborratsOK = 0;
public int FitxersEsborratsKO = 0;
public int CarpetesSenseFitxers = 0;
public int CarpetesPwdIncorrecte = 0;
public int CarpetesJaDesxifrades = 0;
public int CarpetesSenseFitxerConfiguracio = 0;
public string AString()
{
StringBuilder SB = new StringBuilder();
SB.AppendFormat("Fitxers desxifrats OK: {0}{1}", FitxersDesxifratsOK, Environment.NewLine);
SB.AppendFormat("Fitxers desxifrats KO: {0}{1}", FitxersDesxifratsKO, Environment.NewLine);
SB.AppendFormat("Fitxers esborrats OK: {0}{1}", FitxersEsborratsOK, Environment.NewLine);
SB.AppendFormat("Fitxers esborrats KO: {0}{1}", FitxersEsborratsKO, Environment.NewLine);
SB.AppendFormat("Carpetes sense fitxers: {0}{1}", CarpetesSenseFitxers, Environment.NewLine);
SB.AppendFormat("Carpetes pwd incorrecte: {0}{1}", CarpetesPwdIncorrecte, Environment.NewLine);
SB.AppendFormat("Carpetes ja desxifrades: {0}{1}", CarpetesJaDesxifrades, Environment.NewLine);
SB.AppendFormat("Carpetes sense fitxer config: {0}{1}", CarpetesSenseFitxerConfiguracio, Environment.NewLine);
return SB.ToString();
}
}
I una altra:
class clsDadesVerificacioRetorn
{
public int FitxersVerificats = 0;
public int FitxersHashDiferent = 0;
public int FitxersEsborrats = 0;
public int FitxersMidaDiferent = 0;
public string AString()
{
StringBuilder SB = new StringBuilder();
SB.AppendFormat("Total fitxers OK: {0}.{1}", FitxersVerificats, Environment.NewLine);
SB.AppendFormat("Hash KO: {0}.{1}", FitxersHashDiferent, Environment.NewLine);
SB.AppendFormat("Esborrats: {0}.{1}", FitxersEsborrats, Environment.NewLine);
SB.AppendFormat("Mida diferent: {0}.{1}", FitxersMidaDiferent, Environment.NewLine);
return SB.ToString();
}
}
I l'última:
class clsDadesXifratRetorn
{
public int FitxersXifratsOK = 0;
public int FitxersXifratsKO = 0;
public int FitxersEsborratsOK = 0;
public int FitxersEsborratsKO = 0;
public int FitxersReadonly = 0;
public int FitxersTamany0 = 0;
public int FitxersOcults = 0;
public int CarpetesJaXifrades = 0;
public int CarpetesSenseFitxerConfiguracio = 0;
public string AString()
{
StringBuilder SB = new StringBuilder();
SB.AppendFormat("Fitxers xifrats OK: {0}{1}", FitxersXifratsOK, Environment.NewLine);
SB.AppendFormat("Fitxers xifrats KO: {0}{1}", FitxersXifratsKO, Environment.NewLine);
SB.AppendFormat("Fitxers esborrats OK: {0}{1}", FitxersEsborratsOK, Environment.NewLine);
SB.AppendFormat("Fitxers esborrats KO: {0}{1}", FitxersEsborratsKO, Environment.NewLine);
SB.AppendFormat("Fitxers readonly: {0}{1}", FitxersReadonly, Environment.NewLine);
SB.AppendFormat("Fitxers tamany 0: {0}{1}", FitxersTamany0, Environment.NewLine);
SB.AppendFormat("Fitxers ocults: {0}{1}", FitxersOcults, Environment.NewLine);
SB.AppendFormat("Carpetes ja xifrades: {0}{1}", CarpetesJaXifrades, Environment.NewLine);
SB.AppendFormat("Carpetes sense fitxer config: {0}{1}", CarpetesSenseFitxerConfiguracio, Environment.NewLine);
return SB.ToString();
}
}
|