วันพุธที่ 21 พฤษภาคม พ.ศ. 2568

รู้จักกับ "แฮช" (Hash) หัวใจสำคัญของบล็อกเชน

blockchain

สวัสดีครับ กลับมาพบกันอีกครั้งกับ #พุธขุดบล็อกเชน หลังจากบทความแรกที่เราได้อธิบายไปแล้วว่าบล็อกเชนคืออะไร และได้กล่าวถึงว่า “แฮช” (hash) เป็นส่วนสำคัญที่ทำให้การแก้ไขข้อมูลในบล็อกเชนแทบเป็นไปไม่ได้ ในบทความที่สองนี้ เราจะมาทำความรู้จักแฮชกันให้ลึกซึ้งยิ่งขึ้นครับว่ามันคืออะไรกันแน่

แฮช (Hash) คืออะไร?

แฮช หรือถ้าจะเรียกเต็ม ๆ ก็คือ แฮชรหัสลับ (cryptographic hash) เป็นหนึ่งในหัวข้อสำคัญของ วิทยาการรหัสลับ (cryptography) แนวคิดของแฮชสามารถเปรียบเทียบได้กับแนวคิดของลายนิ้วมือครับ คงทราบกันแล้วนะครับว่าคนแต่ละคนจะมีลายนิ้วมือไม่ซ้ำกัน แนวคิดของแฮชก็คือการสร้าง "ลายนิ้วมือ" ให้กับข้อมูลดิจิทัล

นั่นคือการสร้างฟังก์ชันที่เรียกว่า ฟังก์ชันแฮชรหัสลับ (cryptographic hash function) ซึ่งจะทำหน้าที่แปลงข้อมูลที่มีขนาดใด ๆ ก็ตาม (เช่น ข้อความยาว 20,000 ตัวอักษร, 100 ตัวอักษร หรือแม้แต่ไฟล์รูปภาพ) ให้เป็นค่าที่มีความยาวคงที่อีกค่าหนึ่ง (เช่น มีความยาว 64 ตัวอักษร) ค่าที่ถูกแปลงมานี้ เราเรียกว่า ค่าแฮช (hash value) หรือเรียกสั้น ๆ ว่า แฮช

คุณสมบัติสำคัญคือ:

  • ข้อมูลที่เหมือนกัน เมื่อผ่านฟังก์ชันแฮชเดียวกัน จะได้ ค่าแฮชเหมือนกันเสมอ
  • ข้อมูลที่ต่างกัน มี โอกาสน้อยมาก ที่จะได้ค่าแฮชที่เหมือนกัน หรือที่เรียกว่า การชนกัน (collision) ของแฮช ซึ่งตรงนี้ก็คล้ายกับลายนิ้วมือของคนครับ คือยังมีความเป็นไปได้ที่คนสองคนจะมีลายนิ้วมือตรงกัน แต่โอกาสนั้นก็จะน้อยมาก ๆ

ตัวอย่างของฟังก์ชันแฮชรหัสลับ (ในบทความนี้จะขอเรียกสั้น ๆ ว่าฟังก์ชันแฮช) ที่ใช้กันแพร่หลายก็เช่น:

  • SHA-256 (Secure Hash Algorithm 256-bit): ใช้ในบิตคอยน์ (Bitcoin)
  • Keccak-256: ใช้ในอีเธอเรียม (Ethereum)

ตัวเลข "256" ในที่นี้คือจำนวนบิตของค่าแฮชที่ได้ครับ หมายความว่าไม่ว่าข้อมูลต้นฉบับจะมีขนาดเท่าใด ทั้งสองฟังก์ชันนี้จะสร้างค่าแฮชที่มีขนาด 256 บิตเสมอ หรือถ้าแปลงเป็นไบต์ก็คือ 32 ไบต์ (โดย 1 ไบต์ มี 8 บิต)

คุณสมบัติสำคัญของฟังก์ชันแฮช

ข้อกำหนดของฟังก์ชันแฮชที่ดี มีดังนี้ครับ:

  1. ทำงานในทิศทางเดียว (One-way function): สามารถแปลงข้อมูลต้นฉบับไปเป็นค่าแฮชได้ง่าย แต่ต้องไม่สามารถแปลงค่าแฮชกลับไปเป็นข้อมูลเดิมได้ (หรือทำได้ยากมากในทางปฏิบัติ)
  2. ทนทานต่อการชนกัน (Collision resistant): ทำให้มีความเป็นไปได้น้อยที่สุดที่ข้อมูลซึ่งแตกต่างกันจะให้ค่าแฮชเดียวกัน
  3. การเปลี่ยนแปลงเพียงเล็กน้อยส่งผลกระทบมาก (Avalanche effect): การเปลี่ยนแปลงข้อมูลต้นฉบับเพียงเล็กน้อย จะต้องได้ค่าแฮชที่แตกต่างกันอย่างสิ้นเชิง ทำให้ไม่สามารถคาดเดารูปแบบได้
  4. คำนวณได้เร็ว (Fast computation): การคำนวณค่าแฮชจากข้อมูลต้นฉบับจะต้องทำได้อย่างรวดเร็ว

ตัวอย่างการทำงานของแฮช และเลขฐานสิบหก

เพื่อให้เข้าใจมากขึ้น มาดูตัวอย่างกันครับ คำว่า "hello" เมื่อนำมาผ่านฟังก์ชัน SHA-256 จะได้ผลลัพธ์ในรูปเลขฐานสิบหกจำนวน 64 หลักดังนี้:

0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

เรานิยมแสดงค่าแฮชในรูปเลขฐานสิบหก (hexadecimal) เพราะมันสั้นกว่าการแสดงออกมาเป็นเลขฐานสอง (ที่เป็น 0 กับ 1 จำนวน 256 ตัว) ครับ โดย 0x ข้างหน้าเป็นเพียงสัญลักษณ์ที่บอกว่านี่คือเลขฐานสิบหก ไม่ได้นับรวมในค่าแฮช

สำหรับคนที่ไม่คุ้นกับเรื่องเลขฐาน สรุปง่าย ๆ แบบนี้ครับ:

  • เลขฐานสิบหกมีสัญลักษณ์ที่แตกต่างกัน 16 ตัว ได้แก่ 0-9 และ a-f
  • 0-9 ก็เหมือนเลขฐานสิบที่เราใช้กันอยู่
  • a แทน 10, b แทน 11, c แทน 12, d แทน 13, e แทน 14, และ f แทน 15
  • เลขฐานสิบหกหนึ่งหลักจะใช้เนื้อที่ในการเก็บข้อมูลสี่บิต
  • จากค่าแฮชข้างบน มีเลขฐานสิบหกทั้งหมด 64 หลัก นั่นคือ หรือ 32 ไบต์ อย่างที่กล่าวมาแล้วนั่นเองครับ

ถ้าใครไม่เข้าใจเรื่องบิตไบต์ ไม่เป็นไรครับ จะคิดง่าย ๆ ว่า ค่าแฮชที่ได้จาก SHA-256 หรือ Keccak-256 จะมีความยาว 64 "ตัวอักษร" ก็ได้ โดยตัวอักษรเหล่านั้นจะเป็นได้แค่ 0-9 และ a-f

คราวนี้ลองเปลี่ยนข้อมูลเพียงเล็กน้อย จากคำว่า "hello" เป็น "helo" (เอาตัว 'l' ออกไปหนึ่งตัว) ค่าแฮชที่ได้จาก SHA-256 จะเป็นดังนี้ครับ:

0xf4e454f802b88d2f64168ff1742e8cf413fd677d38b87cbefb45821f8981b912

จะเห็นได้ว่าค่าแฮชเปลี่ยนไปอย่างมาก และไม่มีรูปแบบที่คาดเดาได้ ทั้ง ๆ ที่ข้อมูลต้นฉบับเปลี่ยนไปเพียงนิดเดียว นี่คือคุณสมบัติ Avalanche Effect ที่กล่าวถึงข้างต้นครับ

อยากลองเล่นดูไหม? ถ้าใครอยากลองทดลองสร้างค่าแฮชด้วย SHA-256 สามารถเข้าไปที่เว็บไซต์ https://academo.org/demos/SHA-256-hash-generator/ สำหรับทดลองได้  ถ้าลองป้อนคำว่า "hello" หรือ "helo" เข้าไป จะได้ค่าแฮชเดียวกับตัวอย่างแน่นอน เพราะข้อมูลเหมือนกันย่อมได้แฮชเดียวกันเสมอ


sha-256-demo-with-hello
ตัวอย่างการทำงานของ SHA-256 Hash Generator 

แฮชในชีวิตประจำวัน: เรื่องของรหัสผ่าน

เจ้าแฮชนี่ ไม่ได้เพิ่งมาใช้ในบล็อกเชนนะครับ ในปัจจุบันนี้เราแทบจะใช้มันเป็นประจำอยู่แล้วโดยไม่รู้ตัว ตัวอย่างที่ชัดเจนที่สุดคือ การล็อกอินเข้าระบบต่าง ๆ ที่ต้องป้อนรหัสผ่าน

หลายคนอาจคิดว่าเซิร์ฟเวอร์ที่เราใช้งานนั้นเก็บรหัสผ่านของเราไว้ตรง ๆ แต่ในความเป็นจริง (สำหรับระบบที่ปลอดภัย) เขาเก็บค่าแฮชของรหัสผ่านของเราครับ เวลาเราป้อนรหัสผ่านเพื่อล็อกอิน ระบบจะ:

  1. นำรหัสผ่านที่เราป้อนไปผ่านฟังก์ชันแฮช
  2. นำค่าแฮชที่ได้ไปเปรียบเทียบกับค่าแฮชที่เก็บไว้ในฐานข้อมูลบนเซิร์ฟเวอร์
  3. ถ้าค่าแฮชตรงกัน แสดงว่าเราป้อนรหัสผ่านถูก (ข้อมูลเหมือนกันจะได้แฮชเหมือนกันเสมอ)
  4. ถ้าค่าแฮชไม่ตรงกัน แสดงว่ารหัสผ่านผิด (ข้อมูลต่างกันจะได้ค่าแฮชที่ต่างกัน)

การที่เซิร์ฟเวอร์ไม่เก็บรหัสผ่านของเราไว้ตรง ๆ ก็เพื่อเพิ่มความปลอดภัยครับ เพราะถ้าฐานข้อมูลที่เก็บรหัสผ่านเกิดถูกแฮก สิ่งที่ผู้ไม่หวังดีได้ไปก็คือค่าแฮช ซึ่งจะเพิ่มความยากในการแกะรหัสผ่าน เพราะอย่างที่กล่าวไป ฟังก์ชันแฮชทำงานทางเดียว ไม่สามารถย้อนกลับจากค่าแฮชไปเป็นข้อมูลต้นทางได้ แฮกเกอร์จะต้องใช้วิธีทดลองเดาสุ่ม (เช่น brute-force หรือ dictionary attack) แล้วดูว่าได้ค่าแฮชตรงกันหรือไม่

นี่คือเหตุผลว่าทำไมการตั้งรหัสผ่านด้วยคำง่าย ๆ ที่อยู่ในพจนานุกรม หรือตั้งรหัสผ่านสั้น ๆ จึงเสี่ยงต่อการถูกแฮกได้ง่าย เพราะแฮกเกอร์ก็มักจะเริ่มจากคำเหล่านั้นก่อน และยิ่งรหัสผ่านสั้น จำนวนความเป็นไปได้ในการผสมคำก็จะน้อยลง ทำให้หารหัสผ่านเจอได้ง่ายขึ้น

และถึงตรงนี้ ผู้อ่านก็คงเข้าใจแล้วนะครับว่า ทำไมเวลาเราลืมรหัสผ่าน แล้วร้องขอไปที่ผู้ให้บริการ เขาถึงไม่ส่งรหัสผ่านเดิมของเรากลับมาให้ แต่จะให้เราตั้งรหัสผ่านใหม่แทน นั่นก็เพราะเขาไม่ได้เก็บรหัสผ่านของเราไว้นั่นเองครับ เขาเก็บเพียงค่าแฮชของรหัสผ่านเรา ดังนั้น จริง ๆ แล้วเขาไม่รู้รหัสผ่านเราหรอกครับ '

ข้อควรระวัง: ถ้าคุณไปใช้บริการของเซิร์ฟเวอร์ใด แล้วพอคุณลืมรหัสผ่าน เขาสามารถส่งรหัสผ่าน "เดิม" กลับมาให้คุณได้ ผมแนะนำให้พิจารณาเลิกใช้บริการนั้นนะครับ เพราะนั่นหมายความว่าเขาเก็บรหัสผ่านของคุณไว้ในฐานข้อมูลแบบตรง ๆ เลย ซึ่งไม่ปลอดภัยอย่างยิ่ง!

แฮช (Hash) กับการทำงานของบล็อกเชน

หวังว่าตอนนี้ทุกคนจะพอมองเห็นภาพคร่าว ๆ แล้วนะครับว่าแฮชคืออะไร และเรานำมาใช้ประโยชน์อะไรกันบ้าง คราวนี้ก็กลับมาดูกันในเรื่องของบล็อกเชนว่านำแฮชมาใช้อย่างไร

ถ้าใครอ่านบทความแรกแล้วคงพอจำกันได้นะครับว่า ภาพรวมแนวคิดของบล็อกเชนก็คือการเก็บข้อมูลใน บล็อก (block) และแต่ละบล็อกจะ เชื่อมโยงกัน (chain) ด้วยแฮช ขอเอารูปเก่ามาลงอีกทีนะครับ


ภาพรวมโครงสร้างบล็อกเชน


จากรูป จะเห็นว่าแต่ละบล็อกแบ่งออกเป็นสองส่วนหลัก:

  1. ส่วนหัวของบล็อก (Block Header): เก็บข้อมูลเกี่ยวกับบล็อกนั้น ๆ
  2. ส่วนข้อมูล (Block Data): เก็บรายการธุรกรรม (transactions)

ในส่วนหัวของบล็อก (ซึ่งจริง ๆ มีข้อมูลมากกว่านี้) ที่เราจะพิจารณาตอนนี้คือ:

  • หมายเลขบล็อก (Block #): ลำดับของบล็อกในเชน
  • ค่าแฮชของบล็อกก่อนหน้า (Previous Hash / Prev Hash): ค่าแฮชของบล็อกที่อยู่ติดกันก่อนหน้าในเชน
  • ค่าแฮชของบล็อกปัจจุบัน (Hash): ค่าแฮชของข้อมูลทั้งหมดในบล็อกนี้ (ทั้งส่วนหัวและส่วนข้อมูล)

โดยบล็อกแรกสุดในบล็อกเชน (หมายเลข 0) เราจะเรียกว่า บล็อกต้นกำเนิด (Genesis Block) ในกรณีของ Genesis Block ค่าในฟิลด์ "แฮชของบล็อกก่อนหน้า" จะเป็นค่าเฉพาะ เช่น ค่า 0 ทั้งหมด (ทุกบิตในฟิลด์นี้มีค่าเป็น 0) เพราะไม่มีบล็อกใดอยู่ก่อนหน้ามัน

การเชื่อมโยงบล็อกด้วยแฮช

ให้สังเกตว่า:

  • บล็อกที่ 1 จะมีค่าในฟิลด์ "แฮชของบล็อกก่อนหน้า" เป็นค่าแฮชของบล็อก 0
  • บล็อกที่ 2 จะมีค่าในฟิลด์ "แฮชของบล็อกก่อนหน้า" เป็นค่าแฮชของบล็อกที่ 1
  • ถ้ามีบล็อกที่ 3 ก็จะเก็บค่าแฮชของบล็อกที่ 2 ในฟิลด์นี้ และต่อเนื่องไปเรื่อย ๆ เมื่อมีบล็อกใหม่ถูกเพิ่มเข้ามาในเชน

การทำเช่นนี้ส่งผลสำคัญอย่างไร? มันทำให้การเปลี่ยนแปลงข้อมูลในบล็อกใด ๆ ก็ตาม มีผลกระทบกับบล็อกที่ตามมาทั้งหมดในเชนทันที! ตัวอย่างเช่น:

  1. ถ้ามีการพยายามแก้ไขข้อมูลในบล็อกที่ 1
  2. ค่าแฮชของบล็อกที่ 1 จะต้องถูกคำนวณใหม่ (เพราะข้อมูลเปลี่ยน ค่าแฮชก็เปลี่ยน)
  3. เพื่อให้บล็อกที่ 1 ยังคงเชื่อมต่อกับบล็อกที่ 2 อย่างถูกต้อง ค่าแฮชใหม่ของบล็อกที่ 1 นี้ จะต้องถูกนำไปเก็บในฟิลด์ "แฮชของบล็อกก่อนหน้า" ของบล็อกที่ 2
  4. แต่เมื่อข้อมูลในส่วนหัวของบล็อกที่ 2 (คือ Prev Hash) เปลี่ยนไป ก็ต้องคำนวณค่าแฮชของบล็อกที่ 2 ใหม่อีกครั้ง
  5. และก็ต้องนำค่าแฮชใหม่ของบล็อกที่ 2 นี้ ไปใส่ในฟิลด์ "แฮชของบล็อกก่อนหน้า" ของบล็อกที่ 3... ทำแบบนี้ต่อไปเรื่อย ๆ จนสุดปลายของเชน

ซึ่งการไล่แก้ไขข้อมูลและคำนวณแฮชใหม่ทั้งหมดนี้ อาจไม่มีทางทำได้ทันถ้ามีบล็อกใหม่ถูกเพิ่มเข้ามาในเชนตลอดเวลา

โพรโทคอลฉันทามติ (Consensus Protocol) และความปลอดภัย

ยิ่งไปกว่านั้น โพรโทคอลฉันทามติ (Consensus Protocol) ซึ่งเป็นกลไกที่ใช้ในการทำให้ข้อมูลในบล็อกเชนตรงกันในทุกเครื่องคอมพิวเตอร์ที่อยู่ในเครือข่าย (เช่น Proof-of-Work ที่บิตคอยน์ใช้) ยังทำให้การหาค่าแฮชของบล็อกใหม่ (ที่มีคุณสมบัติตามที่โพรโทคอลกำหนด) ใช้เวลาและความพยายามในการคำนวณมากขึ้นไปอีก ผลก็คือ ในทางปฏิบัติแทบไม่มีความเป็นไปได้เลยที่จะมีการแก้ไขข้อมูลที่อยู่ในบล็อกเชนได้ และต่อให้มีใครสามารถแก้ข้อมูลในเชนของตัวเองได้สำเร็จ ก็แทบไม่มีประโยชน์ เพราะข้อมูลนั้นถูกเก็บไว้หลายชุดในเครือข่าย การตรวจสอบยืนยันก็จะทำได้อย่างรวดเร็ว เพียงแค่ดูจากค่าแฮชของบล็อกล่าสุดก็เห็นได้แล้วว่าเชนไหนที่มีข้อมูลไม่ตรงกับเครื่องส่วนใหญ่ในเครือข่าย

(รายละเอียดของ Proof-of-Work จะมีการพูดถึงในบทความต่อ ๆ ไปนะครับ ถ้าใครสนใจก็รออ่านได้ แต่ถ้าไม่สนใจก็ไม่จำเป็นต้องรู้รายละเอียด แค่เข้าใจว่าการเชื่อมโยงบล็อกด้วยแฮชนั้นทำไปเพื่ออะไรก็เพียงพอแล้ว)

Merkle Tree: เพิ่มความมั่นใจและความโปร่งใส

นอกจากนี้ ตามแนวคิดของบล็อกเชน ยังมีการนำแฮชมาใช้อย่างชาญฉลาดอีกขั้น คือการสร้างแฮชของรายการธุรกรรมทุกตัวที่ถูกส่งเข้ามา และยังเอาแฮชของรายการธุรกรรมที่ได้ มาสร้างเป็นโครงสร้างแบบต้นไม้แล้วแฮชต่อเนื่องกันขึ้นไปอีกชั้น ๆ วิธีนี้เรียกว่าการสร้าง Merkle Tree

โดยสุดท้ายแล้วที่ราก (root) ของต้นไม้ (tree) นี้ ที่เรียกว่า Merkle Root ก็จะคือ ค่าแฮชค่าเดียวที่เป็นตัวแทนรายการธุรกรรมทั้งหมดในบล็อกนั้น ค่า Merkle Root นี้จะถูกเก็บไว้ในส่วนหัวของบล็อก


Merkle-Tree-Example
ตัวอย่าง Merkle Tree

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

(รายละเอียดของ Merkle Tree ก็จะมีการพูดถึงในบทความต่อ ๆ ไปเช่นกันครับ และเช่นเดียวกัน ถ้าใครไม่สนใจรายละเอียดก็ไม่จำเป็นต้องรู้ แค่เข้าใจว่า Merkle Tree นี้สนับสนุนแนวคิดของบล็อกเชนที่ว่า "แก้ยาก แต่ตรวจสอบได้ง่าย" ก็พอแล้วครับ)

สรุป

ถึงตรงนี้ ทุกท่านก็คงพอเข้าใจกันแล้วนะครับว่า "แฮช" คืออะไร และมีความสำคัญอย่างไรกับเทคโนโลยีบล็อกเชน ไม่ว่าจะเป็นการสร้างความน่าเชื่อถือ การป้องกันการแก้ไขข้อมูล และการตรวจสอบความถูกต้องของข้อมูล

หวังว่าจะได้ประโยชน์จากบทความนี้นะครับ แล้วพบกันใหม่บทความต่อไปของ #พุธขุดบล็อกเชน ครับ!

ไม่มีความคิดเห็น:

แสดงความคิดเห็น