TheTime Posted February 24, 2012 Report Posted February 24, 2012 //Late night tutorial wannabeDin neincredere fata de managerele de parole (password managers) existente pe net, m-ai facut eu unul personal in C#. Una dintre problemele aparute imediat a fost cum sa-mi stochez datele in baza de date astfel incat sa fie in siguranta chiar daca baza de date ajunge pe maini curioase.Cu putin google si ceva wiki, am reusit sa-mi creez o clasa ce cripteaza si decripteaza un string intr-un mod suficient de sigur, cred eu.Full code:using System;using System.Text;using System.Security.Cryptography;using System.Windows.Forms;namespace KeyMemo{ class locker { public locker() { } public string Cripteaza(string mesaj, string cheie) { string str = ""; UTF8Encoding UTF8 = new UTF8Encoding(); //creez un convertor in md5 si un encoder TDSA MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); TripleDESCryptoServiceProvider TDSA = new TripleDESCryptoServiceProvider(); try { // cheie => md5 hash byte[] cheieMD5 = md5.ComputeHash(UTF8.GetBytes(cheie)); //setari pentru encoderul TDSA TDSA.Key = cheieMD5; TDSA.Mode = CipherMode.ECB; TDSA.Padding = PaddingMode.PKCS7; //criptam mesajul ICryptoTransform crypt = TDSA.CreateEncryptor(); str = Convert.ToBase64String(crypt.TransformFinalBlock(UTF8.GetBytes(mesaj), 0, UTF8.GetBytes(mesaj).Length)); } catch (Exception exc) { MessageBox.Show("A aparut o eroare: \n\n" + exc.ToString(), "Eroare!", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { md5.Clear(); TDSA.Clear(); } return str; } public string Decripteaza(string cod, string cheie) { string str = ""; UTF8Encoding UTF8 = new UTF8Encoding(); //creez un convertor in md5 si un encoder TDSA MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); TripleDESCryptoServiceProvider TDSA = new TripleDESCryptoServiceProvider(); try { // cheie => md5 hash byte[] cheieMD5 = md5.ComputeHash(UTF8.GetBytes(cheie)); //setari pentru encoderul TDSA TDSA.Key = cheieMD5; TDSA.Mode = CipherMode.ECB; TDSA.Padding = PaddingMode.PKCS7; //criptam mesajul ICryptoTransform crypt = TDSA.CreateDecryptor(); str = UTF8.GetString(crypt.TransformFinalBlock(Convert.FromBase64String(cod),0,Convert.FromBase64String(cod).Length)); } catch (Exception exc) { MessageBox.Show("A aparut o eroare: \n\n" + exc.ToString(), "Eroare!", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { md5.Clear(); TDSA.Clear(); } return str; } }}Cum functioneaza? Cam asa: Folosim algoritmul 3DES cu o cheie de 128 biti pentru criptare. Mai exact, trimit ca parametri stringul pe care vreau sa-l criptez si cheia (in plain text). Cheia o transform intr-un hash md5 ca sa ma asigur ca am o cheie de 128 biti// cheie => md5 hash byte[] cheieMD5 = md5.ComputeHash(UTF8.GetBytes(cheie));Apoi aplic algoritmul (care este built-in in C#) pentru stringul meu si cheia in md5: TripleDESCryptoServiceProvider TDSA = new TripleDESCryptoServiceProvider();//setari pentru encoderul TDSA TDSA.Key = cheieMD5; TDSA.Mode = CipherMode.ECB; TDSA.Padding = PaddingMode.PKCS7;//criptam mesajul ICryptoTransform crypt = TDSA.CreateEncryptor(); str = crypt.TransformFinalBlock(UTF8.GetBytes(mesaj), 0, UTF8.GetBytes(mesaj).Length);In final, trec stringul obtinut prin Base64 ca sa-l aduc la o forma adecvata pentru stocarea in baza de date:str = Convert.ToBase64String(crypt.TransformFinalBlock(UTF8.GetBytes(mesaj), 0, UTF8.GetBytes(mesaj).Length));Criptarea obtinuta are formula Base64(3DSA(textInitial,MD5(Cheie))). Pare a fi suficient de complicat si de ambiguu pentru a putea dormi linistit, dar mi-am mai luat o masura de precautie in program: cheia folosita pentru criptare este parola de logare in program. Parola este retinuta in baza de date ca fiind Base64( 3DSA (Parola,MD5(Parola)), deci nu poate fi decriptata, astfel logarea in program se va face pe baza compararii stringului din baza de date cu criptarea parolei introduse de utilizator. Daca cele doua se potrivesc, atunci retinem parola in program.Restul datelor criptate au cheia parola de mai sus (care se presupune a fi stiuta doar de cel care se autentifica in program), deci criptarea este sigura.Decriptarea decurge asemanator:- parametri: string in Base64, parola in plain text;- parola => MD5(parola)- se decodeaza stringul din base64- se decripteaza textul folosind stringul de la pasul anterior si cheia din md5.Asadar, parolele din baza de date pot fi decriptate doar dupa ce utilizatorul a introdus de la tastatura parola. Pare a fi o metoda de criptare buna, zic eu. Ce parere aveti?Daca vreti si voi managerul de parole, dati un PM. In versiunea actuala are ceva din tema de culori RST (negru cu verde), suport pentru mai mai multe persoane (utilizatori diferiti), Adaugari de conturi, sortari, cautari dupa cateva criterii, editari de conturi, validari pe campuri in timp real, tab index corect, tasta Enter face cam ce ar trebui sa faca... Nu l-am testat decat pe win7 x86, rezolutie 1680x1050, deci ar putea aparea probleme de incompatibilitate (desi i-am facut si installer).Printuri:Omuletul KeyMemoLike sau rep daca v-a fost util ceva de pe aici, sau injurati daca v-am irosit timpul degeaba Noapte buna! 3 Quote
Starker Posted March 2, 2012 Report Posted March 2, 2012 Suna interesant dar cum sta cu timpul de compilare? E un proiect frumusel dar e si practic din punct de vedere al compilarii? Quote
TheTime Posted March 3, 2012 Author Report Posted March 3, 2012 Partea de criptare si decriptare se face instant. Am gandit programul astfel incat sa nu criptez sau decriptez parole decat atunci cand utilizatorul vrea sa le adauge/modifice, sau sa le vada. Timpii de latenta in aplicatie apar atunci cand interactionez cu baza de date, dar asta este o alta poveste. Quote
me.mello Posted March 21, 2012 Report Posted March 21, 2012 "Cu putin google si ceva wiki, am reusit sa-mi creez o clasa ce cripteaza si decripteaza un string intr-un mod suficient de sigur, cred eu." Cu riscul de a-mi lua warn....esti pamant vasile doar pentru simplu fapt ca zici ca e facut de tine...ma baiatule pe cand era codul asta pe net tu habar nu aveai de programare sau c# in sine, si dat fiind faptul tin minte ca am facut o funcite asemanatoare bazanduma pe cudul scris mai sus...bineinteles nu de tine facut. Fa tu un functia asta da introdu IV si byte return.Linia asta de cod da de gol multi ratati aspiranti la acest cod... "UTF8.GetBytes(mesaj)"Doar o simpla idee nu am ce sa ma laud cu ea din moment ce 80% e dupa snv: Public Shared Function Decrypt(ByVal bytData() As Byte, _ ByVal sKey As String, _ Optional ByVal tMode As CipherMode = CipherMode.ECB, _ Optional ByVal tPadding As PaddingMode = PaddingMode.PKCS7) As Byte() Dim keyArray As Byte() Dim hashmd5 As New MD5CryptoServiceProvider() keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(sKey)) hashmd5.Clear() Dim tdes As New TripleDESCryptoServiceProvider() tdes.Key = keyArray tdes.Mode = tMode tdes.Padding = tPadding Dim cTransform As ICryptoTransform = tdes.CreateDecryptor() Dim resultArray As Byte() = cTransform.TransformFinalBlock(bytData, 0, bytData.Length) tdes.Clear() Return resultArray End FunctionMi-am permis sa-mi bag putin nasul in cod insa in general e aceiasi prostie....si daca esti baiat destept iti dai seama ca nu va functiona niciodata cu un text mare...ei bine da-ti tu seama de ce sau poti sa-mi dai pm sa-ti dau eu ceva mai bun bazandu-ma pe aceasta idee..PS: pupincuristi ca tine se gasesc oriunde...insa daca vii dupa un forum ceva sa nu crezi ca pari interesant prin faptul ca zici ca e facut de tine...nu pare forumul asta plin de coduri insa stai tu linistit ca multi de aici au vazut mai mult decat se lauda. Quote