Wednesday, December 19, 2007

Cryptography Simplified in Microsoft.NET

ตอนที่ 2 เพิ่มความปลอดกัยของ Hash Algorithm ด้วย Salt

จาก ตอนที่ 1 บทนำ และ Hash Algorithm ได้กล่าววิธีการเข้่ารหัสแบบ on-way หรือ แบบทางเดียว (ถอดรหัสไม่ได้) โดยได้เสนอวิธีของการทำ Hash ด้วย RSA และ SHA1 พร้อมกับ แสดงตัวอย่างของโค้ดไปบ้างแล้ว มาตอนที่ 2 นี้ผมก็ยังอยู่ในเรื่องของ Hash ครับ ซึ่งเป็นเรื่องของการใช้้ Hash อย่างปลอดภัยครับ

เพิ่ม Salt ใน Hash เพื่อควารมปลอดภัยยิ่งขึ้น

ปัญหาอย่างหนึ่งของการ Hash คือ หากมี user 2 คนกำหนด Password เหมือนกัน เขาทั้งคู่ก็จะได้ Hash data เดียวกันทุกประการ ดังนั้นถ้าผมเป็น Hacker แล้วสามารถเข้าไปดูใน table ที่เก็บรหัสผ่านได้ ผมก็จะเห็น user 2 คนมี Hash data เหมือนกัน ผมสามารถเดาได้ว่า Password นั้นน่าจะเป็นเพียงคำง่ายๆ ก็จะลองทำ dictionary attack ดู เรามีวิธีแก้ไข คือ การเพิ่มคำที่เป็นเอกลักษณ์(Unique) เข้าไปใน Password แล้วจึงค่อยทำการ Hash

คำที่เป็นเอกลักษณ์นี้ก็คือ Salt นั่นเอง

แต่ในการใช้ Salt นั้น เราก็ต้องเก็บ Salt ไว้ด้วยเช่นกัน เพื่อใช้เป็นส่วนหนึ่งของ Password ในการ Hash เมื่อ user ทำการล๊อกอินเข้าสู่ระบบ และเพื่อเป็นการปลอดภัยของ Salt เช่นกัน เราจึงควรเก็บ Salt ไว้แยกออกจากตารางที่เก็บ User id และ Password

วิธีในการเพิ่ม Salt เข้าไปใน Password

ขอยกตัวอย่างวิธีที่ง่ายที่สุดก่อนคือ การนำข้อมูลส่วนอื่นๆ ของ user เช่น ชื่อ นามสกุล อีเมลล์แอดเดรส หรือ รหัสพนักงาน เข้าไปใน Password แล้วจึงทำการ Hash แต่วิธีนี้มีข้อเสียคือ เนื่องจากเราต้องเก็บ Salt ไว้แยกจากตารางข้อมูล user id และ Password ดังนั้นมันดูเป็นการตั้งใจเกินไปหากเราจะแยกเก็บ ชื่อ หรือ นามสกุล ออกไปจากตารางนี้ และ Hacker ก็ฉลาดมากพอที่จะเข้าใจในสิ่งที่เรากำลังทำอยู่

วิธีที่ดีกว่า คือ การสร้างคำแบบสุ่ม โดยอาศัยคลาสใน .NET Framework ชื่อ RNGCryptoServiceProvider โดยคลาสนี้จะสร้าง array ของ byte แบบสุ่มตามขนาดที่เรากำหนดขึ้นเอง แล้วจึงนำ array ของ byte นี้มาใช้เป็น Salt เพื่อทำการ Hash ต่อไป

โค้ดฟังก์ชันการสร้าง Salt
โดยคืนค่ากลับมาเป็น String ที่สุ่มมาแล้ว

Private Function CreateSalt() As String
Dim byteSalt(8) As Byte
Dim rng As New Security.Cryptography.RNGCryptoServiceProvider

rng.GetBytes(byteSalt)

Return Convert.ToBase64String(byteSalt)
End Function


เมื่อเราทำการ Hash ก็ให้ Concat ค่า Salt กับ Password เข้าด้วยกันแล้วจึงทำการ Hash

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SaltTextBox.Text = CreateSalt()
TextBox2.Text = HashText(SaltTextBox.Text & TextBox1.Text)
End Sub


ส่วนฟังก์ชัน Hash ยังคงเดิม

Private Function HashText(ByVal TextToHash As String) As String
Dim SHA1 As System.Security.Cryptography.SHA1CryptoServiceProvider
Dim byteValue() As Byte
Dim byteHash() As Byte

' Instanciate SHA1
SHA1 = New System.Security.Cryptography.SHA1CryptoServiceProvider
byteValue = System.Text.Encoding.UTF8.GetBytes(TextToHash)

byteHash = SHA1.ComputeHash(byteValue)

SHA1.Clear()

Return Convert.ToBase64String(byteHash)
End Function


ผลลัพธ์ เมื่อทำการ Hash ข้อมูลเดียวกันด้วย Salt 2 ครั้ง ก็จะได้ Hash data ไม่เหมือนกัน




อย่าลืมว่าการใช้ Salt เราต้องเก็บค่า Salt ไว้ด้วยเพื่อใช้ในการ Hash ข้อมูลเมื่อ user ทำการล๊อกอินเข้ามา โดยต้องหาที่เก็บ Salt ให้ปลอดภัยด้วย
.

Wednesday, December 12, 2007

Cryptography Simplified in Microsoft.NET

ตอนที่ 1 บทนำ และ Hash Algorithm

บทนำ

ในการเก็บข้อมูลที่สำคัญหรือเป็นความลับในคอมพิวเตอร์นั้น เพื่อให้มีความปลอดภัยจากการเข้าถึงของบุคคลที่ไม่เกี่ยวข้อง หรือจากการขโมยข้อมูล เราควรมีการทำ Cryptography เพื่อปกป้องข้อมูลของเรา

Cryptography เป็นศาสตร์ของการแปลงอักขระที่มีความหมายให้เป็นอักขระที่ไม่มีความหมาย ทำให้มนุษย์ไม่สามารถอ่านออกได้

ศาสตร์นี้มีมานานหลายปีแล้ว มีมาก่อนคอมพิวเตอร์เสียอีก ซึ่ง Microsoft เองนั้นได้พัฒนา API สำหรับการทำ Cryptography มาตั้งแต่ Windows 95 จนมาถึง .NET ได้มีคลาสใหม่ๆ ซึ่งห่อหุ้ม Algorithm ในการทำ Cryptography ไว้ เพื่อให้ง่ายในการใช้งาน ผ่าน property และ method


มารู้จักกับ Hash Algorithm

หากคุณต้องการเก็บ password ให้ปลอดภัยจากการมองเห็น คุณจะต้องสร้าง hash ของข้อมูล

Hash เป็น Algorithm แบบทางเดียว หรือ one-way algorithm ในการแปลงข้อมูล ซึ่งเมื่อแปลงข้อมูลไปแล้วจะไม่สามารถแปลงข้อมูลกลับไปเป็นข้อมูลก่อนที่จะแปลงได้อีก

นักพัฒนาส่วนใหญ่ใช้ฐานข้อมูลในการเก็บ password ซึ่งทำให้ผู้ที่มีสิทธิในการเข้าถึงข้อมูลสามารถมองเห็น password ในฐานข้อมูลได้ ดังนั้นควร hash password ก่อน แล้วจึงค่อยเก็บลงในฐานข้อมูล เมื่อ user ป้อน password จึงค่อย hash password ที่ user ได้ป้อนเข้ามา และนำไปเปรียบเทียบกับ hash data ที่เก็บอยู่ในฐานข้อมูลอีกที ดังนั้นจะไม่สามารถดู password ของ user ได้ว่าคืออะไร เพราะมันได้ถูก hash ไว้แล้ว และไม่สามารถแปลงกลับมาเพื่ออ่านได้อีก

การ hash เป็นกระบวนการที่เปลี่ยนข้อมูลเดิมเล็กน้อย และเข้ากระบวนการผลิต hash data ออกมา โดยข้อมูลที่ต่างกันจะได้ hash data ที่ไม่เหมือนกัน และเป็นไปไม่ได้เลยที่จะได้ hash data ที่เหมือนกัน
สำหรับนักพัฒนาของ .NET แล้วมีวิธีการทำ hash ให้เลือกใช้มากมาย แต่ที่พบเห็นโดยทั่วไปหรือใช้บ่อยๆ คือ SHA1 และ MD5

ตัวอย่างโค้ดของฟังก์ชัน SHA1 (ต้อง import the namespace System.Security.Cryptography ด้วย)


Private Function HashText(ByVal TextToHash As String) As String
Dim SHA1 As SHA1CryptoServiceProvider
Dim bytValue() As Byte
Dim bytHash() As Byte

' สร้างอ๊อบเจ็คของ Crypto Service Provider
SHA1 = New SHA1CryptoServiceProvider

' แปลงจาก String ไปเป็น array ของ byte
bytValue = System.Text.Encoding.UTF8.GetBytes(TextToHash)

' ทำการ Hash ซึ่งจะคืนค่าออกมาเป็น array ของ byte
bytHash = SHA1.ComputeHash(bytValue)

SHA1.Clear()

' คืนค่า String จาก hash value
Return Convert.ToBase64String(bytHash))

End Function


ถ้าให้ Hash ข้อมูลคำว่า “Paul” จะได้ hash data คือ

w2h6uYgMJt/nq5ZqihcBteAXwv8=


แต่ถ้าเป็นคำว่า “Pauly” จะได้ hash data คือ

proywxJ0znMpGF5sbB18+7GSAsM=


จะเห็นได้ว่า แม้ข้อความจะเปลี่ยนไปเพียงเล็กน้อย เมื่อทำการ hash ข้อมูลออกมากลับทำให้ hash data แตกต่างกันอย่างสิ้นเชิง ด้วยวิธีการนี้ทำให้การ hash มีประโยชน์มาก ซึ่งทำให้ยากในการหารูปแบบหรือในการถอดข้อมูลดั้งเดิมออกมาจากข้อมูลที่เข้ารหัสไว้แล้วได้

ส่วน MD5 นั้นจะเหมือนกับ SHA1 เปลี่ยนแต่ Provider เท่านั้น


Private Function HashTextMD5(ByVal TextToHash As String) As String
Dim md5 As MD5CryptoServiceProvider
Dim bytValue() As Byte
Dim bytHash() As Byte

md5 = New MD5CryptoServiceProvider

bytValue = System.Text.Encoding.UTF8.GetBytes(TextToHash)

bytHash = md5.ComputeHash(bytValue)

md5.Clear()

Return Convert.ToBase64String(bytHash))
End function

การเลือกใช้ Hash Algorithm

กลไกของการ hash ข้อมูลแต่ละวิธีนั้นมีรูปแบบการทำงานคล้ายกัน แต่มีความแตกต่างอยู่ที่ขนาดของ key ที่ใช้ในการสร้าง hash หากใช้ key ที่ใหญ่ขึ้นก็จะทำให้การเข้ารหัสมีความซับซ้อนมากขึ้น
  • SHA1 ใช้ keyขนาด 160 – bit
  • MD5 ใช้ keyขนาด 120 – bit
ดังนั้น SHA1 จึงมีความปลอดภัยมากกว่า MD5

อีกประเด็นหนึ่งในการพิจารณา คือ ความเป็นไปได้ในการชนกัน (Collision) ของ hash data ทั้งในทางทฤษฎีและในทางปฏิบัติ ซึ่งการชนกันนั้น คือ คำ 2 คำเมื่อทำการ hash แล้วได้ Hash data เดียวกัน
  • SHA1 ไม่มีความเป็นไปได้ในการชนกันเลยทั้งทางทฤษฎีและทางปฏิบัติ
  • MD5 มีโอกาสชนกันได้ในทางทฤษฎี แต่ในทางปฏิบัติไม่มีโอกาสชนกันเลย
สรุป ให้เลือกใช้ algorithm ที่เหมาะกับระดับความปลอดภัยที่คุณต้องการ

พบกันใหม่ในตอนที่ 2 ครับ
.

Monday, December 3, 2007

Preview Visual Basic 2008 Express Edition

Download เสร็จแล้วครับ VS2008 Express Edition
เป็นไฟล์ ISO ประมาณ 800 MB ใช้เวลา download 2 ชั่วโมงครึ่ง กับความเร็ว 100 kbps
เมื่อ download มาแล้ว ก็ทำการแตกไฟล์ออกมาโดยใช้โปรแกรม DAEMON ก็จะได้ไฟล์ติดตั้งทั้งหมด 2.68 GB ใหญ่โตมากขนาดแค่ Express edition เท่านั้นนะ

หน้าตาขณะเริ่มติดตั้ง ซึ่งมีให้เลือกว่าจะติดตั้งตัวใดบ้าง
ผมเริ่มที่ตัว Visual Basic 2008 ก่อนละกัน


เมื่อติดตั้งเสร็จแล้วเปิดโปรแกรมขึ้นมา ยังไม่เห็นความแตกต่างกับ VS2005


เอาโลโก้ไปดูกันชัดๆ


เมื่อ New project จะเห็นได้ว่ามี WPF ซึ่งเคยเป็น Extension ของ VS2005 รวมอยู่ใน 2008 แล้ว


และเมื่อจะ Add Item เข้าใน Project จะเห็น Template ใหม่ๆ เพิ่มเข้ามา เช่น LINQ (อ่านว่า ลิ๊ง), Service-based Database, User Control (WPF)



และเมื่อเข้าไปยัง property ของ project จะพบกับ My Extensions ที่แปลกตา


นี่ยังแค่ Visual Basic 2008 Express นะครับ ยังไม่ได้ติดตั้ง Web Developer 2008 เลย ก็ยังพบว่ามีอะไรๆ มากมายให้เราศึกษาเพิ่มเติมจากเดิมอีกแล้วล่ะครับ

ส่งท้าย สำหรับ Web Developer จะมีลูกเล่นเพิ่มเติมจาก VS2005 มากมาย เช่น WCF, AJAX, JavaScript Intellizence ไว้จะ preview ให้ชมกันครับ
.

Saturday, December 1, 2007

การ import/export ข้อมูลระหว่าง mySql กับ SQL Server 2000

ผมมีงานนึงที่ต้อง Import และ Export ข้อมูลไปมาระหว่าง MySql กับ SQL Server 2000 โดยผ่านตัว DTS จึงต้องหาวิธีการที่จะทำดังกล่าว แล้วผมก็พบทางออกที่ง่ายที่สุดคือการใช้ MySQL-Connector-odbc

ผมได้ download ตัว MySql-Connector-Odbc จากไซต์ www.mysql.com และทำการติดตั้งบนเครื่อง



ในตอนแรกที่โอนข้อมูลผ่าน MySqlODBC จะพบปัญหาภาษาไทยเป็นอักขระผิดเพี้ยนไปเราต้องปรับค่าใน ODBC ที่เรากำหนดขึ้นมาเล็กน้อยครับดังนี้



ให้เลือก Charater Set เป็น tis620 ครับก็สามารถแก้ไขปัญหาภาษาไทยได้ครับ

.