הצפנה סימטרית
בהצפנה סימטרית, הכוונה היא שניתן לבצע הצפנה של הטקסט(encryption) והפיכת הטקסט המוצפן לטקסט קריא שוב(decryption), בעזרת אותו מפתח. זאת אומרת שאם יש לי את הסיסמא(המפתח) אני יכול גם להצפין קוד וגם לקרוא אותו, להבדיל משיטות אחרות שבהם יש מפתח שיכול רק להצפין למשל (נראה בע"ה בפוסטים אחרים...)
טוב, אז איך זה הולך...
קודם נבחר שיטת הצפנה, דוט נט מציע מספר אלגוריתמים שמבצעים הצפנה סימטרית, אולם רק אחד מהם הוא בקוד מנוהל, ולכן נבחר אותו וניצור אובייקט חדש
// using System.Security.Cryptography;
RijndaelManaged myAlg = new RijndaelManaged();
למרות שמפתח ההצפנה (סיסמא) אמור להיות סיסמא אחת, בפועל יש לנו 2 סיסמאות (הסיסמא השניה נקראת IV – וקטור האיתחול ובעצם מגבירה את רמת הבטיחות, אבל לשם הפשטות נתייחס אל שניהם כסיסמאות)
ניצור לנו 2 סיסמאות
String pass1=”mypassword1”;
String pass2=”mypassword2”;
כדי שאלגוריתם ההצפנה יוכל להשתמש בסיסמאות עלינו להפוך אותם למערך של בתים באורך קבוע של 32 ו 16 בתים בהתאמה.
נהפוך את הסטרינגים למערך בתים ונשתמש בפונקציית עזר שתבצע את בדיקת האורך:
byte[] password1= Encoding.UTF8.GetBytes(pass1);
password1= SetArraySize(password1, 32);
byte[] password2= Encoding.UTF8.GetBytes(pass2);
password2= SetArraySize(password2, 16);
נהפוך המידע שברצונו להצפין למערך של בתים:
String clearText=”my credit card number”;
byte [] data= Encoding.UTF8.GetBytes(clearText);
כעת ניתן לאלגוריתם ההצפנה את הסיסמאות:
myAlg.Key = key;
myAlg.IV = IV;
כעת ניצור את האובייקט שישתמש באלגוריתם כדי להצפין את המידע :
ICryptoTransform encryptor = myAlg.CreateEncryptor();
ניצור אובייקט שיכיל את התוצאה של ההצפנה:
MemoryStream outstream = new MemoryStream ();
נגדיר לאובייקט ההצפנה לבצע הצפנה (ולא קריאה מטקסט מוצפן)
CryptoStream encryptStream = new CryptoStream (outstream, encryptor, CryptoStreamMode.Write);
ונבצע את ההצפנה:
encryptStream.Write(data, 0, data.Length);
encryptStream.Close();
והתוצאה התקבלה כמערך של בתים:
byte [] result= outstream.ToArray();
ניתן כמובן להפוך לסטרינג קריא :
String encryptedText= Convert.ToBase64String(result);
זהו... עכשיו, כדי שהצד השני יוכל לקרוא את הטקסט המוצפן, הוא צריך לקבל את הסטרינג המוצפן וכמובן את 2 הסיסמאות/מפתחות שבהם השתמשנו, שזה אחד החסרונות בהצפנה סימטרית- להעביר את המפתח לצד השני...
בהנחה שהצד השני קיבל את הטקסט המוצפן ואת המפתחות, הפעולות שהוא אמור לבצע הן כמעט זהות לתהליך ההצפנה:
ליצור את אלגוריתם ההצפנה
RijndaelManaged myAlg = new RijndaelManaged();
לאתחל אותו עם 2 המפתחות שהוא קיבל
myAlg.Key = key;
myAlg.IV = IV;
להמיר את הטקסט המוצפן למערך של בתים שוב
byte [] encrypted= Convert.Frombase64String(encryptedText);
ליצור את הזרם שממנו יקרא אובייקט ההצפנה את מערך הבתים:
MemoryStream instream = new MemoryStream (encrypted);
היכן לשמור את התוצאה:
byte [] result = new byte [instream.Length];
כעת השינוי החשוב- ניצור את אובייקט ההצפנה עם הוראה לקרוא מטקסט מוצפן:
ICryptoTransform decryptor = myAlg.CreateDecryptor();
CryptoStream decryptStream = new CryptoStream (instream, decryptor, CryptoStreamMode.Read);
ונקרא את הטקסט:
decryptStream.Read(result, 0, result.Length);
התוצאה נמצאת כעת ב result , ניתן להפוך לסטרינג שוב:
String clearText= Encoding.UTF8.GetString(result);
להורדת קבצי המקור והפרוייקט