Pages

Tuesday, March 22, 2011

දත්ත Encrypt කිරීම හා Decrypt කිරීම - Asymmetric Key Encryption

පසුගිය ලිපියෙන් කථා කලේ Symmetric key encryption ගැන. එතනදි වෙන්නෙ Encrypt කරන්න වගේම Decrypt කරන්නත් එකම Key එකක් භාවිතා කිරීමක්. අද ලිපියෙන් කථා කරන්නෙ Asymmetric key encryption ගැන එහෙමත් නැත්නම් Public key encryption ගැන. මෙහිදී Encrypt කරන්න එක Key එකකුත් Decrypt කරන්න තවත් Key එකකුත් භාවිතා කරනවා. මෙහි Encrypt කිරීමට භාවිතා කරන Key එක Public key වශයෙනුත් Decrypt කරන්න භාවිතා කරන Key එක Private key එක වශයෙනුත් හඳුන්වනවා. පහත රූපයෙන් දැක්වෙන්නෙ මේ ආකාරයට Encrypt කිරීම හා Decrypt කිරීම කරනු ලබන ආකාරයයි.


දැන් අපි සරලව විමසා බලමු මෙය සිදුවන ආකාරය. යම් දත්තයක් හුවමාරු කරගැනීමට අවශ්‍ය වන පාර්ශව දෙකක් සිටිනවා. දත්තය යවන පාර්ශවය Sender යනුවෙනුත්, එම දත්තය ලැබෙන පාර්ශවය Recipient යනුවෙනුත් හඳුන්වනවා. මම මුලින් සඳහන් කලා Encrypt කරන්නත් Decrypt කරන්නත් වෙන වෙනම Keys දෙකක් අවශ්‍ය බව. මෙහිදී මෙම Keys දෙකම සාදනු ලබන්නේ Recipient විසිනුයි. ඒසේ සාදනු ලබන Keys දෙකෙන් Private key එක Recipient ලඟ සුරක්ෂිතව තබා ගෙන Public key එක පමණක් Sender වෙත යවයි. ඉන්පසු Sender විසින් මෙම Public key එක මඟින් දත්තය Encrypt කර එය Recipient වෙත යවයි. දැන් Recipient ලඟ ඇති Private key එක භාවිතා කර එම දත්තය Decrypt කර ගත හැක.

Asymmetric key encryption ක්‍රමය ප්‍රමාණයෙන් විශාල දත්තයක් Encrypt කිරීමට සුදුසු වන්නේ නෑ. ඊට හේතුව නම් මෙය Symmetric key encryption ක්‍රමය තරම් වේගවත් නොවීමයි. එම නිසා සමහර අවස්ථාවන් වලදී Asymmetric key encryption ක්‍රමය හා Symmetric key encryption යන ක්‍රම දෙකම එකවිට යොදා ගෙන දත්ත හුවමාරුව සිදුකරනු ලබයි. මේ සඳහා එක් උදාහරණයක් වන්නේ HTTPS Protocol එකෙහි භාව්තයයි. (HTTPS යනු HTTP හා SSL යන Protocols දෙකෙහි එකතුවකි.) Gmail, Yahoo වැනි Email සේවාවන් වලදී මෙන්ම වෙනත් ආරක්ෂාකාරීව දත්ත හුවමාරු කරගැනීමට අවශ්‍ය වෙබ් අඩවිවල මෙම Protocol එක භාවිතා කරයි. මෙය සිදුවන ආකාරය පහත රූපයෙන් දැක්වේ.


මෙහි දැක්වෙන්නේ Web browser එකක් හා Web server එකක් අතර සිදුවන පනිවුඩ හුවමාරුවකි. අංක වලින් දක්වා ඇත්තේ පනිවුඩ හුවමාරුව සිදුවන අනුපිලිවෙලයි.

1. Web browser එක මඟින් Web server එක වෙත ආරක්ෂිත සබඳතාවයක් ඇති කර ගැනීම සඳහා ඉල්ලීමක් යැවීම. (https://mail.google.com වැනි ඉල්ලිමක්)

2. Web server එක මඟින් Public key එකක් හා Private key එකක් සදා ඉන් Public key එක SSL Certificate එක සමඟ Web browser එක වෙත එවීම.

3. Web browser එක මඟින් SSL Certificate එකෙහි වලංගුතාවය පරීක්ෂාකර බලා එය වලංගු එකක් නම් Symmetric key encryption සඳහා භාවිතා කල හැකි Key එකක් සාදා එය Web server එක විසින් එවනු ලැබූ Public key එක මඟින් Encrypt කර (Asymmetric key encryption ක්‍රමයට) එය Web server එක වෙතට යැවීම.

4. Web server එක Web browser එක මඟින් Encrypt කර එවනු ලැබූ Key එක තමා ලඟ ඇති Private key එක මඟින් Decrypt කර ගැනීම. (Asymmetric key encryption ක්‍රමයට) දැන් Web browser එක සතුව හා Web server එක සතුව Symmetric key encryption සඳහා භාවිතා කල හැකි Key එක පවතින අතර එය භාවිතා කර ආරක්ෂිත පණිවුඩ හුවමාරුව සිදුකර ගැනීම.

මෙහිදී Symmetric key encryption සඳහා භාවිතා කරන Key එක හුවමාරු කර ගැනීම සඳහා පමනක් Asymmetric key encryption ක්‍රමය යොදා ගෙන ඇති අතර අනෙකුත් දත්ත හුවමාරු කර ගැනීම සඳහා Symmetric key encryption ක්‍රමය යොදා ගෙන ඇත.

අපි ඊලඟට බලමු Asymmetric key encryption ක්‍රමයට දත්ත Encrypt කිරීම හා Decrypt කිරීම .NET භාවිතයෙන් කරන ආකාරය.

මේ සඳහා අපි භාවිතා කරන්නේ RSACryptoServiceProvider Class එකයි. මෙය භාවිතා කර දත්ත Encrypt කිරීමත් Decrypt කිරීමත් Key pair එකක් (Public key එක හා Private key එක) සකස් කරගැනීමත් කරන්න පුළුවන්. RSACryptoServiceProvider Class එක භාවිතා කර Key pair එකක් සකස් කර ගත් පසු එයින් Public key එක Export කර ගැනීමෙන් එය දත්ත Encrypt කරගැනීම සඳහා භාවිතා කරන්න පුළුවන්. මේ සඳහා RSACryptoServiceProvider Class එකෙහි ToXmlString Method එක භාවිතා කල හැකිය. මෙහි Parameter එක වශයෙන් false යෙදීමෙන් Public key එක පමණක් Export වේ. මෙහි Parameter එක වශයෙන් true යෙදීමෙන් Public key එක මෙන්ම Private key එකත් Export කර ගත හැකිය. මෙහිදී Keys Export වන්නේ XML Format එකෙනි. එම නිසා පහසුවෙන් මෙය පරිඝණක දෙකක් අතර හුවමාරු කර ගත හැකිය.

අනෙක් වැදගත් කාරණය වන්නේ Encrypt කරන ලද දත්තයක් නැවත Decrypt කර ගැනීම සඳහා Private key එක වෙනම ගබඩා කරගෙන සිටිය යුතු වීමයි. මෙම Key එක පරිඝණකයේ ගබඩා කිරීම හා Decrypt කිරීමේදී නැවත එය ලබා ගැනීමට .NET Framework එකට ස්වයංක්‍රීයව සිදුකල හැකියි. RSACryptoServiceProvider Class එකෙහි PersistKeyInCsp Method එක භාවිතා කර Private key එක පමණක් පරිඝණකයේ ගබඩා කල හැකිය. මීට සහය වීම සඳහා තවත් Class එකක් භාවිතා කල යුතුය. එය නම් CspParameters Class එකයි. මෙය භාවිතා කරන අන්දම පහත Code එකෙන් දැක්වේ.
CspParameters csp = new CspParameters();
csp.KeyContainerName = "privatekey";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
rsa.PersistKeyInCsp = true;
මෙහි csp යනුවෙන් CspParameters Object එකක් සකස් කර ඇත. ඉන් පසු එහි KeyContainerName වලට යම් නමක් දිය හැකිය. මම මෙහිදී privatekey යනුවෙන් නම සඳහන් කර ඇත. මෙහිදී සිදුවන්නේ එම නමින් Container එකක් සකස් කර ගැනීමයි. ඉන්පසු rsa යනුවෙන් RSACryptoServiceProvider Object එකක් සාදා එහි Constructor එකට csp Object එක ලබා දී ඇත. අවසාන වශයෙන් මෙහිදී සිදුවන්නේ rsa Object එක මඟින් සකස් කරන Private key එක privatekey යනුවෙන් Container එකක් සකස් කර එහි ගබඩා කිරීමයි. Decrypt කිරීමකදී මෙම Private key එක අවශ්‍ය වූ විට ස්වයංක්‍රීයව එය ලබා ගත හැක.

දැන් අපි සරල උදාහරණයකින් මෙය විමසා බලමු. මා මේ සඳහා වෙන වෙනම Application දෙකක් සකස් කර ගන්නවා, එකක් Key pair එක සකස් කර එය Export කර ගැනීමට හා Decrypt කිරීමටත්, අනෙක Export කරන ලද Public key එක ලබා ගෙන එය භාවිතා කර File එකක් Encrypt කිරීමටත් යොදා ගන්නවා.

පළමු Application එක පහත පරිදි Code කර ගන්න පුළුවන්.
void ExportKey() {
   CspParameters csp = new CspParameters();
   csp.KeyContainerName = "privatekey";
   RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
   rsa.PersistKeyInCsp = true;
   string xml = rsa.ToXmlString(false);
   StreamWriter writer = new StreamWriter(@"c:\key.xml");
   writer.Write(xml);
   writer.Close();
}
මෙහිදී සිදුවන්නේ ras Object එක මඟින් නිර්මාණය කරන Private key එක පරිඝණකයේ ගබඩා කිරීමත්, Public key එක XML File එකක් වශයෙන් ගබඩාකර ගැනීමත්ය.
void Decrypt() {
   CspParameters csp = new CspParameters();
   csp.KeyContainerName = "privatekey";
   RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
   FileStream input = new FileStream(@"C:\encrypted file.txt", FileMode.Open, FileAccess.Read);
   byte[] encdata = new byte[input.Length];
   input.Read(encdata, 0, (int)input.Length);
   input.Close();
   byte[] decdata = rsa.Decrypt(encdata, false);
   FileStream output = new FileStream(@"C:\decrypted file.txt", FileMode.Create, FileAccess.Write);
   output.Write(decdata, 0, decdata.Length);
   output.Close();
}
මෙහිදී සිදුවන්නේ privatekey යනුවෙන් සඳහන් Container එකෙන් Private key එක ලබා ගෙන එමඟින් encrypted file.txt යන File එක Decrypt කර එය decrypted file.txt යනුවෙන් Save කර ගැනීමයි.

අපගේ දෙවැනි Application එක පහත පරිදි විය යුතුයි.
void Encrypt() {
   RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
   StreamReader reader = new StreamReader(@"c:\key.xml");
   rsa.FromXmlString(reader.ReadToEnd());
   FileStream input = new FileStream(@"C:\original file.txt", FileMode.Open, FileAccess.Read);
   byte[] data = new byte[input.Length];
   input.Read(data, 0, (int)input.Length);
   input.Close();
   byte[] encdata = rsa.Encrypt(data, false);
   FileStream output = new FileStream(@"C:\encrypted file.txt", FileMode.Create, FileAccess.Write);
   output.Write(encdata, 0, encdata.Length);
   output.Close();
}
මෙහිදී මුලින්ම rsa Object එක මඟින් XML File එකක් වශයෙන් තියෙන Public key එක ලබා ගනියි. ඒ සඳහා FromXmlString Method එක භාවිතා කර ඇත. ඉන් පසු එම Public key එක භාවිතා කර original file.txt යනුවෙන් සඳහන් File එක Encrypt එය encrypted file.txt යනුවෙන් Save කර ගනියි.

මෙය භාවිතා කිරීමේදී මුලින්ම පලමු Application එකෙහි ExportKey Method එක Call කර පසුව දෙවන Application එකෙහි Encrypt Method එක Call කරන්න. පසුව Encrypt වූ File එක Decrypt කර ගැනීමට පලමු Application එකෙහි Decrypt Method එක Call කරන්න.

2 comments:

Anonymous said...

වැදගත් ලිපියක්. මේ ගැන මමත් හොය හොයා හිටියේ දිගටම ලියන්න.

Anonymous said...

very informative post.Thanks for sharing. keep it up...:D

Post a Comment