Tags: | Categories: Security Posted by talgiladi on 12/7/2009 1:43 PM | Comments (0)
הפעם נדבר על הצפנה אסימטרית. מה הכוונה? ובכן, החיסרון הכי גדול של הצפנה סימטרית הוא כיצד להעביר לצד השני את המפתח/סיסמא. הרי הסיבה העיקרית שרצינו להשתמש בהצפנה היא כי אנחנו לא בוטחים בדרך שהמידע עובר בה ובאנשים שיראו אותו בדרך, אז איך נעביר את המפתח באותו הדרך??אז יש פיתרון... הצפנה אסימטרית. הפעם אין מפתח אחד שיכול גם להצפין וגם לפתוח את ההצפנה, אלא יש מפתח אחד (מפתח פרטי) שיכול גם להצפין וגם לפענח את ההצפנה, ויש מפתח אחד (מפתח ציבורי) שיכול רק להצפין. אז מה יצא לנו מזה? ככה, אנחנו מפרסמים לכולם את המפתח הציבורי שלנו, אז הם יכולים כעת להצפין את המידע מאצלהם, ואז לשלוח אלינו, ורק אנחנו עם המפתח הפרטי יכולים לפענח את ההצפנה... נחמד...ואם אני רוצה לשלוח להם תשובה מוצפנת בחזרה? אז שוב, או שהצד השני ישלח לי מפתח ציבורי משלו, ואז לאחר שאצפין את התשובה עם המפתח שלו, אחזיר לו את המידע המוצפן והוא יפענח אותו עם המפתח הפרטי שלו, או, שבעזרת המפתח הציבורי ששלחתי לצד השני בהתחלה, הוא יצפין לי מפתח/סיסמא להצפנה סימטרית ואז פשוט נמשיך את השיחה שלנו בעזרת הצפנה סימטרית(שזו השיטה הסטנדרטית שבה עובד SSL) . למה שיטה זו עדיפה? ובכן, ההצפנה האסימטרית דורשת הרבה מאמץ מהמעבד והיא מאוד איטית ביחד לשיטה הסימטרית.ועכשיו לקצת קוד:
קודם ניצור זוג מפתחות , אם עדיין אין לנו:המחלקה ב C# שמשמשת להצפנה אסימטרית נקראת RSACryptoServiceProvider (שלוש אותיות ראשונות על שם בוני האלגוריתם...)
ניצור אובייקט חדש, והוא כבר ייצר עבורנו זוג מפתחות:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();

את המפתח הפרטי (שלנו, שיכול לגם לפענח וגם להצפין) ניצור באמצעות הפונקציה ToXmlString עם פרמטר true להוספת המידע של מפתח פרטי בסטרינג שמתקבל:
 
string privateKey= rsa.ToXmlString(true);
 
את המפתח הציבורי ניצור באותה שיטה אך על ידי שליחת ערך false כדי שלא להוסיף את המידע על מפתח פרטי לה
string publicKey = rsa.ToXmlString(false);
כעת נפרסם את המפתח הציבורי שלנו, ומי שירצה להצפין לנו הודעה ישתמש בו בעת ההצפנה:
 ניצור אובייקט הצפנה:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();
 
נאתחל אותו עם המפתח הציבורי:
rsa.FromXmlString(publicKey);
 
נהפוך את המידע שאנו רוצים להצפין למערך בתים:
byte[] clearData=Encoding.UTF8.GetBytes(clearText);
נבצע את ההצפנה :
byte[] encryptedData = rsa.Encrypt(clearData, false);
 
ונהפוך חזרה לסטרינג שניתן לשליחה בתור טקסט באימייל או דף אינטרנט:
 
string encryptedString = Convert.ToBase64String(encryptedData);
 
כעת לאחר שהצד השני שלח לנו את הסטרינג המוצפן, נשתמש במפתח הפרטי לפענח את ההודעה :
ניצור אובייקט הצפנה חדש ונאתחל אותו עם המפתח הפרטי שלנו:
 
 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();
rsa.FromXmlString(privateKey);
 
נהפוך את המידע המוצפן שקיבלנו למערך בתים:
 
 byte[] encryptedData = Convert.FromBase64String(encryptedString);
 
נבצע את הפיענוח:
 
byte[] clearData = rsa.Decrypt(encryptedData, false);
ונהפוך לטקסט קריא:
string clearText = Encoding.UTF8.GetString(clearData);
זהו... די פשוט
 
 
 

להורדת קבצי מקור ופרוייקט

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , | Categories: Security Posted by talgiladi on 1/18/2008 6:08 PM | Comments (4)
Technorati Tags: ,

חתימה דיגיטילית זה בעצם שילוב של מפתח ציבורי/פרטי עם האש. אני רוצה להשיג 2 מטרות בבת אחת- גם לוודא שהמכתב שהנמען קורא הוא המכתב שאני כתבתי והמידע בו לא השתנה, וגם שזהו אכן מכתב שאני כתבתי ולא מישהו אחר. כדי להשיג את המטרה הראשונה, אנחנו משתמשים בהאש – כך אנו מוודאים שהמידע במכתב לא השתנה, והמטרה השניה מושגת על ידי שימוש בהצפנה על ידי המפתח הפרטי שלי- אבל הצפנה רק של ערך ההאש, לא של המכתב כולו.

ועכשיו לקצת קוד:

using System.Security.Cryptography;

 DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

* ניתן באופן זהה במחלקה RSACryptoServiceProvider ושם ניתן גם לציין את האלגוריתם לביצוע ההאש.

המחלקה הזאת תבצע בעצם את פעולת ההאש והחתימה ביחד. אם כבר יש לי מפתח פרטי אזי נאתחל את המחלקה איתו:

dsa.FromXmlString(privatekey);

אם לא אז המחלקה תיצור באופן אוטומטי זוג מפתחות. זיכרו שאנחנו אמורים לספק לצד שמקבל את המידע את המפתח הציבורי שלנו כדי שיוכל לוודא איתו את החתימה, אז אם אין לי עדיין מפתח ציבורי נקבל עכשיו אחד חדש:

 string publickey = dsa.ToXmlString(false);

זהו בעצם, עכשיו פשוט נייצר את החתימה:

 byte[] signature = dsa.SignData(mydata);

וניתן להפוך לסטרינג כמובן:

string result = Convert.ToBase64String(signature);

עכשיו אנחנו מפרסמים את המידע שכתבנו, את המפתח הציבורי ואת החתימה. הצד השני יבצע את הפעולות הבאות כדי לוודא שהחתימה מתאימה:

1. ניצור אובייקט מהמחלקה המתאימה:

DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

2. ניתן לו את המפתח הציבורי שקיבלנו:

dsa.FromXmlString(publickey);

3. וכעת ניתן לו את המידע עצמו ואת החתימה ונקבל ערך בוליאני האם החתימה מתאימה או לא:

 bool match = dsa.VerifySignature(data, signature);

וזהו...

להורדת קבצי המקור והפרוייקט

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , , , | Categories: Security Posted by talgiladi on 9/2/2007 9:38 PM | Comments (7)

נשאלתי לא מזמן לגבי מפתח ציבורי ופרטי, בדרך כלל השימוש הוא שבמפתח הציבורי מצפינים את המידע ובפרטי מפענחים כדי שכולם יוכלו לכתוב לי ורק אני אוכל לקרוא את ההודעות שלהם, אך מה לגבי פעולה הפוכה? שאני אצפין עם המפתח הפרטי וכולם יוכלו לקרוא? מה הטעם תשאלו? פשוט מאוד, אני רוצה לכתוב הודעה ושכולם יוכלו לקרוא, אבל שיהיו בטוחים שאני כתבתי? נשמע מוכר...? ברור כי זו בדיוק הפעולה של חתימה דיגילית... אז מתברר שמישהו במיקרוסופט שכח להוסיף את האפשרות הזאת למפתח פרטי/ציבורי, למרות שלפי ההגדרה של המפתחות זה כן אפשרי... אבל כן נשארה לנו האופציה של חתימה דיגיטלית באמצעות Sign Data
בואו נראה קצת קוד. קודם ניצור מופע מהמחלקה DSACryptoServiceProvider שבאמצעותה תבוצע ההצפנה

DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

כעת ניצור 2 מפתחות - הפרטי שבאצעותו ניתן לחתום מידע ואותו נשמור אצלנו, וציבורי שבאמצעותו ניתן רק להשוות חתימה למידע ולוודא שאכן החתימה שייכת למידע מסוים אך לא ניתן ליצור חתימות חדשות באמצעותו את המפתח הפרטי ניצור באמצעות:

DSAParameters privateKey = dsa.ExportParameters(true);

ואת הציבורי באותה צורה, אך מבלי להכליל את המידע הדרוש כדי לבצע חתימה:

DSAParameters publicKey = dsa.ExportParameters(false);

כעת נבצע את החתימה:

byte[] clearData = Encoding.UTF8.GetBytes(args[0]);
string signedData = Convert.ToBase64String(dsa.SignData(data, 0, data.Length));

ועכשיו אני יכול לשלוח לצד השני את המידע עצמו, את החתימה שעכשיו יצרתי ואת המפתח הציבורי (כמובן שעדיף שהמפתח הציבורי יהיה אצלהם לפני כדי שיהיו בטוחים שהוא אכן שלי...)
הצד השני ינסה להשוות את החתימה למידע כדי לדעת שהמידע אכן הגיע ממני ונחתם על ידי

קודם הוא יצור שוב מופע מהמחלקה שתוודא את החתימה, אך הוא יתן לה את המפתח הציבורי ששלחנו לו בתור פרמטר:

DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
dsa.ImportParameters(publicKey);

כעת המחלקה הזאת יכולה רק לוודא חתימה, ורק את החתימה שלי, אז בואו אכן נוודא:

dsa.VerifyData(clearData, Convert.FromBase64String( signedData));

להורדת הפרוייקט

Technorati Tags: ,,,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5