Thursday, July 29, 2010

การ encrypt/decrypt รูป

การ encrypt/decrypt ก็คงเป็นการเข้ารหัสข้อมูลที่สำคัญ ที่ไม่ต้องการจะเปิดเผยให้ใครรู้
ซึ่งในระหว่างการส่งข้อมูลในแต่ละ tier นั้นอาจจะใช้โปรเเกรมพวก sniffer ดักเอาก็ได้ เพื่อ
ความปลอดภัย เราโปรเเกรมเมอร์จึงต้องเข้ารหัสข้อมูลแล้วก็ใส่รหัสผ่านของเราไว้สำหรับถอดรหัสด้วย

ที่นี้การเ้ข้ารหัสนั้นไม่ว่าภาษาใหนก็ทำได้และมีอัลกอลิทึมให้ใช้กันอย่างหลากหลาย ซึ่งการเข้ารหัส
และถอดรหัสด้วยภาษาเดียวกันอาจจะทำได้ง่ายกว่า การเข้ารหัสด้วยภาษาหนึ่งแล้วไปถอดรหัสอีกภาษาหนึ่ง
ซึ่งในกรณีซึ่งเป็นระบบเเบ็คเอ็นต้องเข้ารหัสรูปบน asp.net(c#) แล้วไปถอดบน iphone ใ่ช้เวลา
ลองผิดลองถูกเกือบสองวันในที่สุดก็ทำได้ครับ

ส่วนสำคัญอยู่ตรงนี้ครับ

byte[] images = File.ReadAllBytes(@"C:\Wallpaper\encrypt.jpg");

string x = Convert.ToBase64String(images);
string result = DecryptString(x, "digix");
byte[] data = Convert.FromBase64String(result);
FileStream fsout = new FileStream(@"C:\Wallpaper\decrypt.jpg", FileMode.CreateNew);
fsout.Write(data, 0, data.Length);
fsout.Flush();
fsout.Close();


เเหล่งข้อมูลที่ใช้ในการศึกษา
http://stackoverflow.com/questions/1373032/c-howto-convert-image-to-binary
http://stackoverflow.com/questions/885237/writing-an-image-to-a-text-file-as-binary-data-c
โค้ดการเข้ารหัส string จาก http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/

///
/// Encrpyts the sourceString, returns this result as an Aes encrpyted, BASE64 encoded string
///

/// a plain, Framework string (ASCII, null terminated)
/// The pass phrase.
///
/// returns an Aes encrypted, BASE64 encoded string
///

public static string EncryptString(string plainSourceStringToEncrypt, string passPhrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passPhrase)))
{
byte[] sourceBytes = Encoding.ASCII.GetBytes(plainSourceStringToEncrypt);
ICryptoTransform ictE = acsp.CreateEncryptor();

//Set up stream to contain the encryption
MemoryStream msS = new MemoryStream();

//Perform the encrpytion, storing output into the stream
CryptoStream csS = new CryptoStream(msS, ictE, CryptoStreamMode.Write);
csS.Write(sourceBytes, 0, sourceBytes.Length);
csS.FlushFinalBlock();

//sourceBytes are now encrypted as an array of secure bytes
byte[] encryptedBytes = msS.ToArray(); //.ToArray() is important, don't mess with the buffer

//return the encrypted bytes as a BASE64 encoded string
return Convert.ToBase64String(encryptedBytes);
}
}


///
/// Decrypts a BASE64 encoded string of encrypted data, returns a plain string
///

/// an Aes encrypted AND base64 encoded string
/// The passphrase.
/// returns a plain string
public static string DecryptString(string base64StringToDecrypt, string passphrase)
{
//Set up the encryption objects
using (AesCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passphrase)))
{
byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt);
ICryptoTransform ictD = acsp.CreateDecryptor();

//RawBytes now contains original byte array, still in Encrypted state

//Decrypt into stream
MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length);
CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read);
//csD now contains original byte array, fully decrypted

//return the content of msD as a regular string
return (new StreamReader(csD)).ReadToEnd();
}
}

private static AesCryptoServiceProvider GetProvider(byte[] key)
{
AesCryptoServiceProvider result = new AesCryptoServiceProvider();
result.BlockSize = 128;
result.KeySize = 128;
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7;

result.GenerateIV();
result.IV = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

byte[] RealKey = GetKey(key, result);
result.Key = RealKey;
// result.IV = RealKey;
return result;
}

private static byte[] GetKey(byte[] suggestedKey, SymmetricAlgorithm p)
{
byte[] kRaw = suggestedKey;
List kList = new List();

for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8)
{
kList.Add(kRaw[(i / 8) % kRaw.Length]);
}
byte[] k = kList.ToArray();
return k;
}

No comments: