วันอาทิตย์ที่ 28 เมษายน พ.ศ. 2556

Hash



ในกระบวนการรักษาความปลอดภัยคอมพิวเตอร์ นอกเหนือจากการดูแลระบบให้ควบคุมสิ่งที่ผู้ใช้หรือผู้บุกรุกให้ไม่สามารถทำงานใดๆ นอกเหนือจากที่กำหนดไว้ กระบวนการเข้ารหัส (Cryptography) นับเป็นสิ่งสำคัญที่ช่วยให้กระบวนการควบคุมนั้นเป็นไปได้จริง กระบวนการเข้ารหัสทุกวันนี้มักสร้างจากตัวประกอบสามตัวหลักได้แก่ ฟังก์ชั่นแฮช, การเข้ารหัสแบบกุญแจสมมาตร (symmetric key), และการเข้ารหัสแบบกุญแจอสมมาตร (asymmetric key) ในตอนแรกจะพูดถึงฟังก์ชั่นแฮชก่อน
ฟังก์ชั่นแฮชนั้นโดยทั่วไปมันคือฟังก์ชั่นที่คืนค่าที่ "ความยาวคงที่" จากข้อมูลที่ความยาวเท่าใดก็ได้ อย่างเช่นที่เราเรียนในวิชาอัลกอริทึมอาจจะใช้ n mod C เพื่อหาค่าแฮชของข้อมูลใดๆ สมมติให้ n ใหญ่ได้ไม่จำกัดและเราต้องไม่ลืมว่าข้อมูลในคอมพิวเตอร์นั้นไม่ว่าจะเป็นข้อมูลใดๆ สุดท้ายแล้วเราสามารถมองข้อมูลเหล่านั้นเป็นตัวเลขจำนวนหนึ่ง (ที่อาจจะมีหลักนับพันล้านหลัก) ผลสุดท้ายค่าแฮชของข้อมูลจะใหญ่ไม่เกินค่า C
แม้เราอาจจะสร้างฟังก์ชั่นแฮชได้ไม่ยากนัก แต่ฟังก์ชั่นแฮชแต่ละฟังก์ชั่นนั้นมีความดีแย่ต่างกันไป จุดสำคัญที่สุดของฟังก์ชั่นแฮช คือ การชนกันของค่าแฮช (collision) ที่ข้อมูลสองชุดกลับมีค่าแฮชตรงกัน เช่น หากเราใช้ฟังก์ชั่นง่ายๆ อย่าง hash(n) = n mod 5 ทุกค่า n ที่ลงท้ายด้วย 5 ก็จะได้ค่าแฮชเป็น 0 เท่ากันทั้งหมด การใช้งานค่าแฮชที่นักเรียนสายคอมพิวเตอร์ทุกคนต้องเรียนกันคือใช้สร้างตารางแฮช

Checksum: เพื่อความถูกต้องของข้อมูล

ฟังก์ชั่นแฮชมีประโยชน์การใช้งานแรกๆ คือการตรวจสอบความถูกต้องของข้อมูล จากความผิดพลาดต่างๆ เช่น ความไม่น่าเชื่อถือของฮาร์ดแวร์, ความผิดพลาดของมนุษย์, หรือจากความเสียจากความผิดพลาดของเครือข่าย ค่าเหล่านี้เรามักเรียกในการใช้งานว่าค่า checksum
ภายในระบบแรมในคอมพิวเตอร์ทั่วไป จะมีการตรวจค่าความถูกต้องข้อมูลในแรมที่เรียกว่า parity bit ได้จากการบวกค่าของทุกหลักในทุกไบต์เข้าด้วยกัน parity = (bit(0) + bit(1) + bit(2) + bit(3) + bit(4) + bit(5) + bit(6) + bit(7)) mod 2 หากข้อมูลมีความผิดพลาด เช่นแรมเสียหาย เมื่ออ่านค่ากลับขึ้นมาค่าที่ได้จะมีโอกาสไม่ตรงกับค่าใน parity bit อยู่ 50% และหากเจอกรณีเช่นนั้นคอมพิวเตอร์ก็จะหยุดทำงาน แรมรุ่นใหม่ๆ อาจจะไม่ใช้เทคนิคนี้แล้วเนื่องจากต้นทุน, พลังงาน, และความเชื่อถือของแรมรุ่นใหม่ๆ ก็สูงขึ้นมากแต่แผงแรมในคอมพิวเตอร์รุ่นเก่าจะมีชิปแรมอยู่ 9 ตัวด้วยเหตุผลนี้
ภายในบัตรประชาชนไทย มีจำนวน 13 หลัก แต่ในความจริงแล้วมีความหมายเพียง 12 หลักเท่านั้นโดยหลักที่ 13 เป็นค่า checksum เราสามารถใส่เลข 12 หลักของบัตรประชาชนใดๆ แล้วหาค่าหลักที่ 13 ได้
def checksum(ssn):
    return (11 - (sum([int(s)*(len(S)-i+1) for (s,i) in zip(S,range(len(S)))]) % 11)) % 10
กระบวนการนี้ทำให้โอกาสที่ผิดพลาดจากการกรอกหมายเลขด้วยมือลดลงไปอย่างมาก โดยค่าที่ได้นั้นเป็น 0-9 การกรอกผิดจะผ่านการตรวจสอบได้ต่อเมื่อกรอกผิดแล้วได้ค่า checksum ตรงกันพอดี
ค่า checksum ที่มีค่าที่เป็นไปได้เพียงหนึ่งหลักหรือกระทั่งหนึ่งบิตอาจจะดูสามารถชนกับค่าอื่นๆ นี่นำมาคำนวณได้โดยง่าย เราอาจจะพบว่าในการกรอกเลขบัตรประชาชนนับล้านๆ ครั้ง อาจจะมีครั้งที่ผิดในหลักพันครั้ง แม้ค่า checksum จะช่วยลดความผิดพลาดนี้แต่ก็ยังคงเหลือความผิดพลาดโดยบังเอิญได้
ฟังก์ชั่น checksum ช่วงหลังจึงมีการพัฒนาให้สามารถคำนวณค่าและได้ผลลัพธ์ที่กำหนดได้ว่าต้องการผลลัพธ์ (ที่ความยาวจำกัด) เป็นความยาวเท่าใด ที่นิยมใช้กันมากในช่วงหนึ่งคือ CRC-32 ที่จริงแล้ว CRC เป็นเพียงการกำหนดกระบวนการคำนวณไว้กว้างๆ เท่านั้น แต่ความยาวของค่าที่ได้มักกำหนดเป็น 32 บิต จึงเรียกว่า CRC-32
CRC-32 สามารถคำนวณค่า checksum เพื่อยืนยันความถูกต้องของข้อความได้เป็นอย่างดี ด้วยความยาวถึง 32 บิตทำให้มีความเป็นไปได้ 4 พันล้านรูปแบบ มันถูกใช้ตรวจสอบความถูกต้องของข้อมูลอย่างกว้างขวาง ทั้งในระบบแลนที่มีการแนบค่า CRC-32 ไปท้ายแพ็กเก็ตเพื่อให้ฝั่งรับสามารถตรวจสอบได้ว่าข้อมูลทั้งหมดที่ได้รับมาถูกต้องหรือไม่ การส่งไฟล์ขนาดใหญ่ที่อาจจะมีข้อผิดพลาดก็สามารถป้องกันได้ด้วยการส่งค่า CRC-32 ไปให้ผู้รับก่อน เมื่อผู้รับได้รับแล้วจึงรันคำสั่ง crc32 (ลินุกซ์ส่วนมากยังติดตั้งคำสั่งนี้เป็นมาตรฐาน สามารถเล่นดูได้) เพื่อคำนวณค่าของไฟล์ที่ดาวน์โหลดมา หากถูกต้องตรงกันก็แสดงว่าค่าที่ได้รับมานั้นถูกต้อง
อย่างไรก็ดีฟังก์ชั่นในกลุ่ม checksum นั้นถูกออกแบบมาเพื่อให้ตรวจพบความผิดพลาดของข้อมูล "โดยไม่ตั้งใจ" และหากมีนักวิเคราะห์ทางคณิตศาสตร์มาหาทางคำนวณย้อนกลับ เพื่อหาข้อมูลที่จะคำนวณได้ค่า checksum ที่ตรงกันแล้วก็เป็นไปได้โดยง่าย ในโปรโตรคอล SSHv1 นั้นออกแบบโดยไม่ตระหนักถึงข้อจำกัดนี้ หลังจากที่ SSHv1 ออกมาในปี 1995 ก็ได้รับความนิยมอย่างสูง คอมพิวเตอร์และอุปกรณ์เครือข่ายจำนวนมากพากันใช้ SSHv1 ในการล็อกอินจากระยะไกลแทนโปรโตคอลเดิมๆ เช่น telnet โดยหวังว่ามันจะให้ความปลอดภัยที่ดีกว่า เพียงสามปีหลังจากออกโปรโตคอลก็เริ่มมีรายงานว่ามีคนสามารถแทรกคำสั่งใดๆ ลงไปในการเชื่อมต่อที่แอดมินกำลังเชื่อมต่ออยู่กับเครื่องเซิร์ฟเวอร์ และสามารถเข้าควบคุมเครื่องแทนได้ในที่สุด (VU#13877)
หลังจากนั้นไม่นาน ซอฟต์แวร์ SSH จากหลายบริษัทก็พยายามเพิ่มโค้ดตรวจสอบการโจมตีด้วยการปลอมแพ็กเก็ตของ SSH แต่ในปี 2001 ก็มีผู้พบว่าโค้ดดังกล่าวมีบั๊กจนทำให้แฮกเกอร์สามารถบุกเครื่องเซิร์ฟเวอร์ได้โดยไม่ต้องดักฟังการเชื่อมต่อแม้แต่น้อย (VU#945216) นับเป็นจุดอวสานของ SSHv1 ที่ผู้ผลิตส่วนมากมักเลิกซัพพอร์ตโปรโตคอลไป และปิดไว้เป็นค่าตั้งต้น แต่บังคับให้ใช้ SSHv2 ที่แข็งแรงกว่าแทน อย่างไรก็ดี เรื่องนี้ทำให้เรามี The Matrix Reloaded ดูกัน (มองจอดีๆ)

Cryptographic Hash

ในค่า checksum นั้นเราอาจจะนิยามได้ว่ามันเป็นฟังก์ชั่นที่ให้ค่าที่ "ถ้าข้อมูลไม่ตรงกันแล้ว จะได้ค่าที่บังเอิญตรงกันได้ยาก" แต่ปัญหาคือแฮกเกอร์นั้นเป็นผู้จงใจอย่างยิ่งที่จะปลอมแปลงข้อมูล
แม้ข้อมูลจะไม่เข้ารหัส แต่หลายกรณีความถูกต้องก็เป็นเรื่องสำคัญเป็นอย่างมาก เราอาจจะดาวน์โหลดไฟล์ซีดีของลินุกซ์สักตัวจากเซิร์ฟเวอร์ใดๆ ก็ได้ในโลก โดยเลือกเซิร์ฟเวอร์ที่ใกล้เรามากที่สุด เพื่อให้ได้ความเร็วสูงสุด แต่เราจะเชื่อได้อย่างไรว่าเจ้าของเซิร์ฟเวอร์นั้นไม่แอบแก้ไข ใส่มัลแวร์ ฯลฯ ลงไปในซีดีก่อนที่จะเปิดให้เราดาวน์โหลด ขณะที่ผู้ผลิตลินุกซ์มักมีทุนไม่มากนัก และจำนวนมากอยู่ด้วยเงินบริจาค ทางออกในเรื่องนี้คือการประกาศค่าแฮชของทุกไฟล์ที่ให้ดาวน์โหลดผ่านทางเว็บกลาง หลังจากนั้นแม้ใครจะดาวน์โหลดผ่านช่องทางใดๆ ก็สามารถทำได้ เมื่อตรวจสอบแล้วว่าค่าแฮชตรงก็สามารถใช้งานได้อย่างสบายใจ
16b0aa028e5a3d6374667e875044b762cb11eae7 *ubuntu-12.10-desktop-amd64+mac.iso
8618058554ffd11e317356ec25885bcb8c1d0b36 *ubuntu-12.10-desktop-amd64.iso
3e8a359ec2665c6ac9e48e8712655bf1d9bcf27f *ubuntu-12.10-desktop-armhf+omap4.img
799b761f1bbea635d7306a5632cbd54c8c27a10b *ubuntu-12.10-desktop-i386.iso
823b66c44fb620479ba43dacfc73d54cc8af65f6 *ubuntu-12.10-server-amd64+mac.iso
e2a48af008ff3c4db6a8235151a1e90ea600fceb *ubuntu-12.10-server-amd64.iso
ddc70bd3dacbc006eb8dc8cdc05fab008c5b07b9 *ubuntu-12.10-server-armhf+omap4.img
e0e48be7ae21003cf0b25591d71d8cdbee7063e7 *ubuntu-12.10-server-i386.iso
5fa95a26aa416204b9229d07c0d389ea921036d5 *ubuntu-12.10-wubi-amd64.tar.xz
b594ae9d40d0644293990b873dfccf50f80c942b *ubuntu-12.10-wubi-i386.tar.xz
c4879ae4e706613bf2682bfd80ef8d429e107a4f *wubi.exe
ตัวอย่างข้างต้นเป็นค่า SHA1 ของไฟล์ Ubuntu 12.10 ใครที่มีไฟล์และติดตั้งไปแล้วอาจจะลองรันคำสั่ง sha1sum เพื่อตรวจสอบซ้ำ (ถ้าไม่ตรงก็ขอให้โชคดี)
คุณสมบัติความทนทานของฟังก์ชั่นแฮชในกลุ่มที่ทนทานต่อแฮกเกอร์ที่เรียกกันว่า cryptographic hash นี้ มีคุณสมบัติด้วยกัน 3 ประการ
  1. ถ้ามีค่า hash(n) อยู่แล้ว แฮกเกอร์ต้องไม่สามารถหาค่า n ได้ภายในเวลาที่สมเหตุผล
  2. ถ้ามีค่า n และ ้hash(n) อยู่แล้ว แฮกเกอร์ต้องไม่สามารถหาค่า m ที่ทำให้ค่า hash(m) == hash(n) ได้ภายในเวลาที่สมเหตุผล
  3. แฮกเกอร์ไม่สามารถหาค่า n และ m ใดๆ ที่ทำให้ hash(n) == hash(m) ภายในเวลาที่สมเหตุสมผล
ในกรณีของไฟล์ที่เปิดให้ดาวน์โหลด หากผู้ที่ดาวน์โหลดรู้อยู่ก่อนแล้วว่าค่าแฮชนั้นคือค่าอะไรก็สามารถตรวจสอบได้ว่าค่าของไฟล์ที่ดาวน์โหลดมานั้นตรงกันหรือไม่ หากแฮกเกอร์ต้องการปลอมไฟล์เพื่อให้ดาวน์โหลดไปใช้งาน จะต้องพยายามสร้างไฟล์ใหม่ขึ้นมาหลายๆ รูปแบบ ในกรณีของ SHA1 นั้นค่าแฮชที่ได้มีความยาว 160 บิต แฮกเกอร์อาจจะต้องสร้างไฟล์มากขึ้น 2160 (ประมาณ 1.46 x 1048) แบบเพื่อให้ได้สักไฟล์หนึ่งที่มีค่าแฮชตรงกัน หากเป็นเช่นนี้แสดงว่าแฮกเกอร์ไม่สามารถทำได้ในเวลาที่สมเหตุสมผลผล
ก่อนหน้านี้ฟังก์ชั่นที่ได้รับความนิยมเป็นอย่างมากคือ MD5 เพราะมันทำงานได้เร็ว และมีประวัติความทนทานค่อนข้างดีมาก แต่ในช่วงสิบปีให้หลังมานี้ ความรู้ด้านการถอดรหัส (cryptanalysis) ของ MD5 ก็เริ่มถูกเผยแพร่มากขึ้นจนสามารถปลอมแปลงกันได้แม้จะใช้ต้นทุนและเวลาที่สูง แต่ในมัลแวร์ Flame ก็ใช้ช่องโหว่นี้ปลอมแปลงใบรับรองของทางไมโครซอฟท์ จนกระทั่งมัลแวร์สามารถผ่านการตรวจสอบของวินโดวส์ไปได้ โดยตัว MD5 นั้นให้ค่าแฮชขนาด 128 บิต แม้จะต้องใช้เวลานับสิบปี (ซึ่งต่ำกว่าที่ออกแบบไว้เดิม) หากใช้คอมพิวเตอร์เครื่องเดียวในการสร้างใบรับรองในรูปแบบต่างๆ เพื่อให้ค่าแฮชตรงกันและสามารถปลอมแปลงได้ แต่หากแฮกเกอร์มีทุนมากพอก็สามารถซื้อคอมพิวเตอร์จำนวนมาก หรือเช่าเครื่อจาก Amazon EC2 นับพันๆ เครื่องเพื่อช่วยกันคำนวณภายในเวลาไม่กี่เดือน
ฟังก์ชั่นแฮชในระดับที่ทนทานต่อการโจมตี ต้องการการทดสอบจากวงกว้างว่ามันทนทานได้จริง การที่ทีมวิจัยหนึ่งๆ ออกแบบฟังก์ชั่นแฮชที่ดูจะทนทานแต่ไม่ได้ถูกทดสอบมากพอ อาจจะทำให้พบช่องโหว่สำคัญได้ภายหลัง ทาง NIST (National Institute of Standards and Technology - NIST, เป็นหน่วยงานกำหนดมาตรฐานภายใต้กระทรวงพานิชของสหรัฐฯ) ก็จัดแข่งขันมาตรฐาน SHA (Secure Hash Algorithm) เคยเป็นหน่วยงานที่ออกฟังก์ชั่นแฮชมาตรฐานสำหรับหน่วยงานต่างๆ ของสหรัฐ โดยตอนแรกออกมาเป็นฟังก์ชั่น SHA และถูกเจาะ (พบวิธีการสร้างค่าที่ให้ค่าแฮชตรงกัน) ในเวลาไม่นาน จนต้องแก้ไขเป็น SHA1 (ตัวแรกเลยได้ชื่อว่า SHA0) ที่ได้รับการยอมรับอย่างกว้างขวาง และใช้ในใบรับรองการเข้ารหัสเว็บส่วนใหญ่ทุกวันนี้
SHA1 เองก็เริ่มมีแนวโน้มว่าอาจจะไม่แข็งแกร่งนัก ทาง NIST แนะนำให้หน่วยงานรัฐทั้งหมดย้ายไปใช้ SHA2 หลังจากปี 2010 และเพื่อสร้างมาตรฐานที่ทนทานในระยะยาวก็จัดแข่ง SHA3 จากทีมวิจัยหลายทีม และเพิ่งได้ผู้ชนะเมื่อปลายปีที่แล้ว
นอกจากการใช้แฮชเพื่อตรวจสอบความถูกต้องของข้อมูลแล้ว หน้าที่สำคัญของแฮชคือการ "ปิดบัง" ว่าข้อมูลนั้นที่จริงแล้วเป็นอะไร กรณีที่ใช้กันมาก เช่น การปิดบังรหัสผ่าน, หรือการปิดบังข้อมูลความลับ
ในระบบ 2-factor authentication ของกูเกิลนั้นเมื่อเปิดโปรแกรมครั้งแรกโปรแกรมจะขอให้ผ่านบาร์โค้ดบนหน้าจอ บาร์โค้ดนั้นคือ "ความลับ" ที่เรากับกูเกิลรู้ร่วมกัน แต่ในกรณีของรหัสผ่าน เราต้องส่งความลับให้กูเกิลทุกครั้งที่ต้องการเข้าใช้บริการ แต่หากเราใช้ฟังก์ชั่นแฮช เมื่อเราแชร์ความลับนี้ร่วมกับกูเกิลแล้ว กระบวนการคือใช้ค่า "เวลา" ไปเชื่อมกับความลับ เช่น หากกูเกิลกำหนดความลับระหว่างเรากับเว็บเป็น "14048a9a" ทุกๆ นาที ฟังก์ชั่นภายในจะแฮชค่าจากนาฬิกา กลายเป็นค่าแฮช HASH("14048a9a"+"Apr 25 05:03:03 ICT 2013") เมื่อเราส่งค่าแฮชนี้ไปยังกูเกิล กูเกิลที่รู้ความลับภายในเช่นเดียวกันจะสามารถใช้นาฬิกาในเครื่องตัวเองคำนวณเวลาออกมาได้แบบเดียวกัน กระบวนการจึงพิสูจน์ตัวตนได้โดยไม่ต้องส่งความลับถึงกันแม้แต่น้อย
กระบวนการนี้มีการใช้งานมานานในโลกองค์กร บริษัทขนาดใหญ่จำนวนมากมี "พวงกุญแจ" พิเศษที่มีตัวเลขแสดงและเปลี่ยนไปทุกนาที หลักการก็ยังคงเดิมคือภายในพวงกุญแจเหล่านี้มีค่าความลับที่ไม่ต้องการเปิดเผยอยู่ภายในและแชร์ร่วมกันกับเซิร์ฟเวอร์ และใช้ค่าเวลาปัจจุบันในการคำนวณตัวเลข

Password Hash

รหัสผ่านนั้นเป็นข้อมูลที่ต้องถูกปิดบังแม้แต่ผู้ดูแลระบบเองรวมถึงหลายครั้งข้อมูลถูกแบ็กอัพเก็บเอาไว้ ผู้ใช้อาจจะใช้รหัสผ่านเดียวกันในหลายบริการ (ซึ่งเป็นนิสัยที่อันตรายต่อความปลอดภัย แต่ผู้ใช้จำนวนมากก็ทำเช่นนี้) ในกรณีสุดวิสัย ฐานข้อมูลรหัสผ่านอาจจะรั่วไหลไปยังแฮกเกอร์ที่เราพบกันได้บ่อยครั้ง การแฮชรหัสผ่านก่อนที่จะเก็บจึงช่วยแก้ปัญหานี้ ข้อมูลที่เก็บอยู่บนเซิร์ฟเวอร์จะเป็นเพียงค่าแฮชที่ไม่ (ควร) มีใครรู้ว่าค่าตั้งต้นของมันเป็นอะไร เช่น บางครั้งแฮกเกอร์ก็เป็นผู้ดูแลระบบหรือผู้ดำเนินการแบ็กอัพเสียเอง หากคนเหล่านี้สามารถรู้ได้ว่ารหัสผ่านคืออะไร พวกเขาอาจจะออกไปล็อกอินบริการผ่านช่องทางปกติ แล้วใช้รหัสผ่านของลูกค้าเพื่อเข้าสู่ระบบได้โดยง่าย
เว็บเฟรมเวิร์คสมัยใหม่จะเก็บรหัสผ่านผู้ใช้เป็นค่าที่แฮชแล้วทั้งหมด เป็นเหตุผลให้เมื่อผู้ใช้ลืมรหัสผ่าน เว็บจะไม่สามารถส่งรหัสผ่านเดิมกลับไปยังผู้ใช้ได้เลย (เพราะไม่มีใครรู้รหัสแล้ว) กระบวนการเดียวที่ทำได้คือการส่งลิงก์ที่เป็นลิงก์สร้างขึ้นเฉพาะ (มักต่อท้ายด้วยสตริงสุ่มยาวๆ ให้เดาไม่ได้) แล้วให้ผู้ใช้กดเข้ามาเปลี่ยนรหัสผ่านได้เท่านั้น
แม้ว่าฟังก์ชั่นแฮชจะทนทานต่อการย้อนกลับหาค่าตั้งต้น แต่พลังของคอมพิวเตอร์ทุกวันนี้กลับสูงมากจนกระทั่งเป็นไปได้ที่จะเก็บค่าความเป็นไปได้ทุกกรณีของแฮช เมื่อเราเห็นค่าแฮชสักค่าหนึ่ง เราอาจจะค้นหามันได้ทั่วไปว่าที่จริงแล้วมันเป็นค่าอะไร เช่น ค่า bf072e9119077b4e76437a93986787ef ยิ่งหากผู้ใช้ใช้รหัสผ่านที่ใช้กันบ่อย โอกาสที่จะพบค่าแฮชที่ตรงกันทำให้รู้รหัสผ่านเริ่มต้นก็มากขึ้น
กระบวนการหลีกเลี่ยงค่าแฮชของค่าที่พบบ่อย ทำให้มีข้อเสนอการเติมค่าเข้าไปอีกชุดหนึ่งก่อนแฮชเพื่อให้ค่าเปลี่ยนไป โดยค่านี้อาจจะเก็บเป็นความลับระหว่างผู้ที่เข้าถึงฐานข้อมูลของรหัสผ่าน โดยเติมค่าที่สุ่มมาอีกชุดหนึ่งต่อท้ายข้อมูลที่จะแฮช ทำให้ค่าแฮชที่ได้ไม่ตรงกับค่าแฮชทั่วไปที่ใช้งานกัน เช่น หากต้องการเก็บค่าแฮช SHA1 ของรหัสผ่าน "1234" แทนที่จะแฮชค่า "1234" โดยตรงซึ่งจะให้ค่าแฮช "1be168ff837f043bde17c0314341c84271047b31" ก็ให้สร้างอักษรสุ่ม เช่น "A1d944" เข้ามาต่อท้ายทำให้ค่าเปลี่ยนไปเป็น "14048a9ac614bd653defca9e63db28d1377c0df4" เมื่อต้องการเทียบค่าอีกครั้ง ไม่ว่าผู้ใช้จะใส่ค่าอะไรเป็นรหัสผ่านก็ให้นำสตริง "A1d944" เข้าไปต่อท้ายทุกครั้ง เรียกกระบวนการนี้ว่า Salt
นอกจากการปิดบังรหัสผ่านแล้ว ยังมีกรณีที่ต้องการปิดบัง เช่น มาตรฐานการเก็บหมายเลขบัตรเครดิตนั้น ไม่ควรเก็บหมายเลขบัตรเครดิตไว้โดยตรงในฐานข้อมูล แต่ให้เก็บค่าแฮช (ที่อาจจะไม่ต้อง Salt) เพื่อใช้ยืนยันว่าผู้ใส่หมายเลขบัตรเครดิตนั้นเป็นลูกค้าที่ใช้บริการร้านค้าอยู่หรือไม่ และใช้หมายเลขที่ลูกค้าเพิ่งใส่มาในการยืนยันไปยังธนาคารเพื่อตัดเงิน การทำเช่นนี้ในกรณีที่ร้านค้าถูกแฮกก็ยังไม่ทำให้หมายเลขบัตรเครดิตของลูกค้าถูกเปิดเผย
แต่ปัญหาของฟังก์ชั่นแฮชยังคงมีประเด็นใหม่ๆ ฮาร์ดแวร์ปัจจุบันได้รับการปรับปรุงอย่างรวดเร็ว ชิปจำนวนมากถูกเพิ่มชุดคำสั่งพิเศษเพื่อเร่งความเร็วในการคำนวณแฮช ทำให้การคำนวณค่าแฮชทำได้เร็วขึ้นเรื่อยๆ ปัญหาความปลอดภัยเกิดขึ้นเมื่อการคำนวณค่าแฮชทำได้อย่างรวดเร็ว ทุกวันนี้การตั้งรหัสผ่านของคนเรามักจำกัดอยู่ที่ไม่เกิน 8 ตัวอักษร ซึ่งหากใช้ตัวอักษรเล็กภาษาอังกฤษทั้งหมดก็จะมีความเป็นไปได้เพียงสองแสนล้านกรณีเท่านั้น ฮาร์ดแวร์ความเร็วสูงและการใช้บริการกลุ่มเมฆทำให้การคำนวณค่าแฮชใหม่ทั้งหมดสำหรับความเป็นไปได้เพียงเท่านี้สามารถทำได้ในเวลาอันสั้น หรือแม้แต่การจำคำสุ่มในภาษาอังกฤษสี่คำ ก็ยังมีความเป็นไปได้เพียง 4.5 ล้านล้านกรณี ในกรณี
เราไม่สามารถเพิ่มความยาวรหัสผ่านไปเรื่อยๆ เพื่อให้มีความเป็นไปได้สูงพอที่แฮกเกอร์จะไม่สามารถไล่คำนวณรหัสผ่านใหม่ทั้งหมดได้ กระบวนการที่พอช่วยได้คือการสร้างฟังก์ชั่นแฮชรูปแบบใหม่ที่ "ช้า" ฟังก์ชั่นทั่วไปอาจจะคำนวณสำเร็จภายในเวลาระดับไมโครวินาที แต่ฟังก์ชั่นแฮชสำหรับรหัสผ่านจะใช้เวลามากกว่านั้นนับพันหรือนับหมื่นเท่า หากใช้สำหรับคำนวณรหัสผ่านผู้ใช้ที่ป้อนรหัสก็มักไม่ส่งผลทำให้การให้บริการช้าลงนัก แต่หากแฮกเกอร์จะไล่รหัสผ่านที่เป็นไปได้ทุกกรณี การช้าลงนับพันเท่าจะทำให้แฮกเกอร์คำนวณทุกค่าที่เป็นไปได้ได้ยากขึ้นมาก (หากออกแบบแข็งแรงพอ น่าจะไม่สามารถทำได้ในช่วงชีวิต) ฟังก์ชั่นเหล่านี้ได้แก่ bcrypt ที่ช้าโดยกระบวนวิธีภายในเองแม้จะช้าแต่แฮกเกอร์ในยุคหลังก็สามารถสร้างฮาร์ดแวร์ผ่านชิป FPGA เพื่อเร่งความเร็วได้ดีขึ้นเรื่อยๆ,มาตรฐานการแฮชที่ช้าที่เป็นมาตรฐานคือ PBKDF2 (แบบเดียวกับที่ 1Password ใช้) โดยกระบวนการแล้วมันคือการคำนวณค่าแฮชด้วยฟังก์ชั่นที่ระบุ โดยสามารถระบุได้เป็นทั้ง SHA1 และ MD5 แล้วคำนวณซ้ำๆ ไปตามจำนวนรอบที่กำหนด โดยแนะนำไม่ต่ำกว่า 1000 รอบ ข้อเสนอใหม่เช่น scrypt สร้างฟังก์ชั่นที่ช้าและต้องการหน่วยความจำสูง ทำให้สร้างฮาร์ดแวร์มาเร่งความเร็วได้ลำบาก (เพราะหน่วยความจำในชิปจะกินพื้นที่สูงมาก)

ส่งท้าย

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


ที่มา http://www.blognone.com/node/43630