الگوريتم متقارن (Symmetric Algorithm )
در روش Symmetric Key Cryptography يک کليد براي encrypt و decrypt
کردن Cipher Text وجود دارد که به آن کليد معمولا secret key گفته ميشود
به همين دليل symmetric ( متقارن ) ناميده ميشود.
متن يا فايلي که با يک کليد و الگوريتم در مبدا ، رمز (encrypt) ميشود با
همان کليد و همان الگوريتم در مقصد باز ميشود. به عبارت ديگر دري که قفل
شد فقط با همان کليد باز ميشود.
در اين روش کليد بايد بين فرستنده و گيرنده secret نگاه داشته شود زيرا که
با داشتن کليد به راحتي ميتوان Cipher Text را Decrypt کرد.
الگوريتمهاي اين روش عبارتند از:
DES ، 3DES ، AES ، IDEA ، Blow Fish ، RC4.
اين روش
معمولا از روش نامتقارن کم هزينهتر است و سريع تر انجام ميشود و معمولا
کليدها خيلي بزرگ هستند و الگوريتمهاي آن چند هزار سال است که در حال
بهبودند و به خوبي شناخته شده هستند. مساله اصلي در اين نوع cryptography
آن است که چگونه کليدي را براي ارتباط به طرف مقابل يعني مقصد اعلام کرد
(چون خط انتقال ممکن است secure نباشد).
يکي از ساده ترين الگوريتمهايي که در روش متقارن استفاده ميشود XOR کردن
معمولي Plain Text با کليد مورد نظر است که اگر دوباره Cipher Text را با
کليد مورد نظر XOR کنيم Plain Text به دست ميآيد و اين به دليل خواص XOR
است.
جالب است بدانيد که نسخه هاي اوليه Yahoo Messenger براي ذخيره کردن
Password ها روي ماشين ، آن را با User Name شما XOR کرده و در registry
قرار ميداد.
به
صورت عمومی انواع الگوریتم های رمز نگاری به دو نوع متقارن و غیر متقارن
تقسیم می شوند.در کد گذاری متقارن کلید مخفی و یا همان پسورد.برای کد
گذاری داده ها به کار می رود.برای رمز گشایی نیز همان کلید مخفی باید به
کار رود . نمونه هایی از این نوع الگوریتم ها شامل Des و Rc2 میشوند.
الگوریتم
نا متفارن از یک جفت کلید به هم مربوط برای رمز نگاری و رمز گشایی استفاده
می کنند . یکی از این کلیدها کلید عمومی نام می گیرد و دیگری کلید مخفی .
داده های کد گذاری شده به وسیله یک کلید عمومی ، تنها به وسیله کلید مخفی
قابل رمز گشایی هستند و بر عکس . و مثالی از آن Rsa است.
یکی دیگر از کامپوننت هایی کلیدی دیگر در مبحث کریپتو گرافی ، توابع Hash هستند . این توابع داده های ورودی را با هر طولی را به به یک داده خروجی با طول اپثابت نگاشت می کنند . توابع Hash عموما
یک طرفه هستند . یعنی داه های رمز نگاری شده توسط آنها برگشت ناپذیر بوده
و برای ایجاد خروجی با طول ثابت و منحصر به فرد کار برد دارند . و عمومی
ترین استفاده آنها تولید امضای دیجیتال در رمز نگاری توسط کلید عمومی است.
این الگوریتم ها در فضای نام System.Security.Cryptography قرار دارد.
حجمش : 3 كيلوبايت
اين لينك دموي ساخته شده با كدهاي لينك قبلي هست .
حجمش : 10 كيلوبايت
following algorithms: MD5, SHA1, SHA256, SHA384, and SHA512.
اينك كدها :
using System;
using CodeProject.Chidi.Cryptography;
namespace CodeProject.Chidi.TestConsole
{
/// <summary>
/// For testing components.
/// </summary>
class clsTest
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
SymCryptography cryptic = new SymCryptography();
string plainText = "Chidi Ezeukwu";
cryptic.Key = "wqdj~yriu!@*k0_^fa7431%p$#=@hd+&";
Console.WriteLine("The Encryption Component Test\n");
Console.WriteLine("=============================\n");
Console.WriteLine("Plain text: " + plainText);
Console.WriteLine("Key: " + cryptic.Key + "\n");
Console.WriteLine("Using default encryption algorithm:");
string TestEnc = cryptic.Encrypt(plainText);
string TestDec = cryptic.Decrypt(TestEnc);
Console.WriteLine("Encrypted text: " + TestEnc+ "\n");
Console.WriteLine("Using RC2 algorithm:");
cryptic = new SymCryptography("rc2");
TestEnc = cryptic.Encrypt(plainText);
Console.WriteLine("Encrypted text: " + TestEnc + "\n");
Console.WriteLine("Using DES algorithm:");
cryptic = new SymCryptography("DES");
TestEnc = cryptic.Encrypt(plainText);
Console.WriteLine("Encrypted text: " + TestEnc + "\n");
Console.WriteLine("Using TripleDES algorithm:");
cryptic = new SymCryptography("TripleDES");
TestEnc = cryptic.Encrypt(plainText);
Console.WriteLine("Encrypted text: " + TestEnc + "\n");
Hash hash = new Hash("SHA1");
string TestHash = hash.Encrypt(plainText);
Console.WriteLine("Using SHA1 hashing algorithm:");
Console.WriteLine("Hashed text: " + TestHash + "\n");
Console.Read();
}
}
}
-----------------------------------------------------------------------------
سورس كد :
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace CodeProject.Chidi.Cryptography
{
#region Symmetric cryptography class...
/// <SUMMARY>Contains methods and properties for
/// two-way encryption and decryption</SUMMARY>
/// Chidi C. Ezeukwu
/// <WRITTEN>May 24, 2004</WRITTEN>
/// <UPDATED>Aug 07, 2004</UPDATED>
public class SymCryptography
{
#region Private members...
private string mKey = string.Empty;
private string mSalt = string.Empty;
private ServiceProviderEnum mAlgorithm;
private SymmetricAlgorithm mCryptoService;
private void SetLegalIV()
{
// Set symmetric algorithm
switch(mAlgorithm)
{
case ServiceProviderEnum.Rijndael:
mCryptoService.IV = new byte[] {0xf, 0x6f, 0x13, 0x2e, 0x35,
0xc2, 0xcd, 0xf9, 0x5, 0x46, 0x9c, 0xea, 0xa8, 0x4b, 0x73,0xcc};
break;
default:
mCryptoService.IV = new byte[] {0xf, 0x6f, 0x13, 0x2e,
0x35, 0xc2, 0xcd, 0xf9};
break;
}
}
#endregion
#region Public interfaces...
public enum ServiceProviderEnum: int
{
// Supported service providers
Rijndael,
RC2,
DES,
TripleDES
}
public SymCryptography()
{
// Default symmetric algorithm
mCryptoService = new RijndaelManaged();
mCryptoService.Mode = CipherMode.CBC;
mAlgorithm = ServiceProviderEnum.Rijndael;
}
public SymCryptography(ServiceProviderEnum serviceProvider)
{
// Select symmetric algorithm
switch(serviceProvider)
{
case ServiceProviderEnum.Rijndael:
mCryptoService = new RijndaelManaged();
mAlgorithm = ServiceProviderEnum.Rijndael;
break;
case ServiceProviderEnum.RC2:
mCryptoService = new RC2CryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.RC2;
break;
case ServiceProviderEnum.DES:
mCryptoService = new DESCryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.DES;
break;
case ServiceProviderEnum.TripleDES:
mCryptoService = new TripleDESCryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.TripleDES;
break;
}
mCryptoService.Mode = CipherMode.CBC;
}
public SymCryptography(string serviceProviderName)
{
try
{
// Select symmetric algorithm
switch(serviceProviderName.ToLower())
{
case "rijndael":
serviceProviderName = "Rijndael";
mAlgorithm = ServiceProviderEnum.Rijndael;
break;
case "rc2":
serviceProviderName = "RC2";
mAlgorithm = ServiceProviderEnum.RC2;
break;
case "des":
serviceProviderName = "DES";
mAlgorithm = ServiceProviderEnum.DES;
break;
case "tripledes":
serviceProviderName = "TripleDES";
mAlgorithm = ServiceProviderEnum.TripleDES;
break;
}
// Set symmetric algorithm
mCryptoService = (SymmetricAlgorithm)
CryptoConfig.CreateFromName(serviceProviderName);
mCryptoService.Mode = CipherMode.CBC;
}
catch
{
throw;
}
}
public virtual byte[] GetLegalKey()
{
// Adjust key if necessary, and return a valid key
if (mCryptoService.LegalKeySizes.Length > 0)
{
// Key sizes in bits
int keySize = mKey.Length * 8;
int minSize = mCryptoService.LegalKeySizes[0].MinSize;
int maxSize = mCryptoService.LegalKeySizes[0].MaxSize;
int skipSize = mCryptoService.LegalKeySizes[0].SkipSize;
if (keySize > maxSize)
{
// Extract maximum size allowed
mKey = mKey.Substring(0, maxSize / 8);
}
else if (keySize < maxSize)
{
// Set valid size
int validSize = (keySize <= minSize)? minSize :
(keySize - keySize % skipSize) + skipSize;
if (keySize < validSize)
{
// Pad the key with asterisk to make up the size
mKey = mKey.PadRight(validSize / 8, '*');
}
}
}
PasswordDeriveBytes key = new PasswordDeriveBytes(mKey,
ASCIIEncoding.ASCII.GetBytes(mSalt));
return key.GetBytes(mKey.Length);
}
public virtual string Encrypt(string plainText)
{
byte[] plainByte = ASCIIEncoding.ASCII.GetBytes(plainText);
byte[] keyByte = GetLegalKey();
// Set private key
mCryptoService.Key = keyByte;
SetLegalIV();
// Encryptor object
ICryptoTransform cryptoTransform = mCryptoService.CreateEncryptor();
// Memory stream object
MemoryStream ms = new MemoryStream();
// Crpto stream object
CryptoStream cs = new CryptoStream(ms, cryptoTransform,
CryptoStreamMode.Write);
// Write encrypted byte to memory stream
cs.Write(plainByte, 0, plainByte.Length);
cs.FlushFinalBlock();
// Get the encrypted byte length
byte[] cryptoByte = ms.ToArray();
// Convert into base 64 to enable result to be used in Xml
return Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0));
}
public virtual string Decrypt(string cryptoText)
{
// Convert from base 64 string to bytes
byte[] cryptoByte = Convert.FromBase64String(cryptoText);
byte[] keyByte = GetLegalKey();
// Set private key
mCryptoService.Key = keyByte;
SetLegalIV();
// Decryptor object
ICryptoTransform cryptoTransform = mCryptoService.CreateDecryptor();
try
{
// Memory stream object
MemoryStream ms = new MemoryStream(cryptoByte, 0, cryptoByte.Length);
// Crpto stream object
CryptoStream cs = new CryptoStream(ms, cryptoTransform,
CryptoStreamMode.Read);
// Get the result from the Crypto stream
StreamReader sr = new StreamReader(cs);
return sr.ReadToEnd();
}
catch
{
return null;
}
}
public string Key
{
get
{
return mKey;
}
set
{
mKey = value;
}
}
public string Salt
{
// Salt value
get
{
return mSalt;
}
set
{
mSalt = value;
}
}
#endregion
}
#endregion
#region Hash Class...
/// <SUMMARY>CHashProtector is a password protection
/// one way encryption algorithm</SUMMARY>
/// Chidi C. Ezeukwu
/// <WRITTEN>May 16, 2004</WRITTEN>
/// <UPDATED>Aug 07, 2004</UPDATED>
public class Hash
{
#region Private member variables...
private string mSalt;
private HashAlgorithm mCryptoService;
#endregion
#region Public interfaces...
public enum ServiceProviderEnum: int
{
// Supported algorithms
SHA1,
SHA256,
SHA384,
SHA512,
MD5
}
public Hash()
{
// Default Hash algorithm
mCryptoService = new SHA1Managed();
}
public Hash(ServiceProviderEnum serviceProvider)
{
// Select hash algorithm
switch(serviceProvider)
{
case ServiceProviderEnum.MD5:
mCryptoService = new MD5CryptoServiceProvider();
break;
case ServiceProviderEnum.SHA1:
mCryptoService = new SHA1Managed();
break;
case ServiceProviderEnum.SHA256:
mCryptoService = new SHA256Managed();
break;
case ServiceProviderEnum.SHA384:
mCryptoService = new SHA384Managed();
break;
case ServiceProviderEnum.SHA512:
mCryptoService = new SHA512Managed();
break;
}
}
public Hash(string serviceProviderName)
{
try
{
// Set Hash algorithm
mCryptoService = (HashAlgorithm)CryptoConfig.CreateFromName(
serviceProviderName.ToUpper());
}
catch
{
throw;
}
}
public virtual string Encrypt(string plainText)
{
byte[] cryptoByte = mCryptoService.ComputeHash(
ASCIIEncoding.ASCII.GetBytes(plainText + mSalt));
// Convert into base 64 to enable result to be used in Xml
return Convert.ToBase64String(cryptoByte, 0, cryptoByte.Length);
}
public string Salt
{
// Salt value
get
{
return mSalt;
}
set
{
mSalt = value;
}
}
#endregion
}
#endregion
}آقای bad boy بازم ممنون از لطفتون
در ضمن درست حدس زدین . این چیزا رو دقیقا واسه کار کلاسی میخوام
البته واسه کلاس کار هم بد نی... (;