Transparent Password Verification

Watchanon Numnam
3 min readOct 4, 2021

ลองมาทำกระบวนการล็อกอินโดยไม่ต้องส่ง Password ไปที่ Server กันดีกว่า

ทั้งหมดนี้เป็นตัวอย่างหนึ่งของการทำ Challenge-response authentication เพียงเท่านั้นที่สามารถนำไปใช้งานเพื่อให้ไม่ต้องส่ง Password ไปที่ Server หรืออาจจะนำไปใช้ควบคู่กับ Biometric API ต่างๆของ Mobile device ก็ได้

Challenge response authentication

ที่มาของรูป https://www.eeweb.com/reliable-challenge-response-system-with-sha/

ขออธิบายแบบง่ายๆไวๆละกัน ถ้า Server ส่ง ค่ามาค่าหนึ่ง แล้วให้ Client ทำการเอา Private key sign ค่านั้นละส่งกลับมายัง Server, Server ทำการตรวจด้วย Public key คู่เดียวกันที่ Client เคยส่งมาไว้ ถ้า Verify ผ่าน ก็แสดงว่า Client คนที่ Sign นี้ตรงกับคนที่เคยให้ Public key กับ server เอาไว้นั่นเอง

Traditional Password Authentication

โดยปกติแล้วกระบวนการ Register เรามักใช้ค่า Username และ Password โดยที่ Username เราจะเก็บไว้เป็น Plaintext ใน Database และจะทำการ Hashing Password โดย one-way algorithm ต่างๆ แล้วทำการเก็บค่า Hash ลงใน Database

เมื่อทำการ Authentication ระบบจะทำการนำ Username และ Password แล้วมา Hash เปรียบเทียบกับที่เก็บไว้ในขั้นตอน Register ถ้าตรงกันก็จะทำงานต่อ แต่หากไม่ ก็จะทำการ Reject

ทั้งหมดดูเหมือนจะดี แต่ถ้าหากมีส่วนไหนทำงานผิดพลาด เช่น แทนที่จะเก็บค่า Password แบบ Hash ลงใน Database แต่ไปเก็บ Plantext หละ หรือลืมที่จะ Random salt ระหว่างที่ Hashing Password ก็จะทำให้เกิดโอกาสที่ Password ที่ Hash มีโอกาสซ้ำกันได้ หรือ เลือกใช้ Hashing Algorithms ที่ง่ายเกินไป

หรือแม้แต่ถ้าระบบเกิด Data Breach, Online attacker อาจจะได้ Password ของเราและลองทำไปใช้กับระบบอื่นๆได้ (*ดังนั้นอย่าใช้ password เหมือนกันทุก website) เพราะในบางที การที่รู้แค่ Hashing Password ก็เพียงพอต่อ Attacker แล้ว

แล้วถ้าเราจะไม่อยากส่ง Password ไปยัง Server เราจะทำยังไงได้บ้าง หรือในบางกรณีที่ Mobile Application มีการใช้งานฟีเจอร์พวก FaceID หรือ Biometric ของเครื่องเราควรจะจัดการอย่างไรดีเมื่อไม่มี Password แล้ว

บ่อยครั้งที่มักเจอว่า Mobile Application มักจะใช้ Username/PIN เป็น password และเมื่อใช้งาน FaceID หรือ Biometric ก็มักจะนำ PIN ไป Encrypt และเอา Secret เก็บไว้ใน Secure Storage ของ Mobile Device หรือบางทีก็เอา PIN ไปเก็บไว้ใน Secure Storage เลย และเมื่อทำการ Authentication ก็จะทำการ Authentication ด้วย PIN เหมือนเดิม

Transparent Password Verification

เริ่มจากขั้นตอนการ Register แทนที่ Client จะทำการสร้าง Account

แทนที่ Client จะทำการส่ง Password มาที่ Server, Client ทำการ Random Salt (16 byte string) จากนั้นใช้ Password-base key derivation function (PBKDF2) เพื่อสร้าง Static key สำหรับ Account (ใช้ Salt + Password สร้าง Static Key)

PBKDF2 function จะรัน 1000 รอบเพื่อสร้าง 32-byte Key การที่ใช้จำนวนรอบที่เยอะไม่ได้สำคัญตอนล็อกอิน แต่จะทำให้ Attacker ต้องใช้เวลาในการ Brute force นานขึ้น

หลังจากที่ Key โดนสร้างขึ้นแล้ว จะใช้ Key ตัวนี้เป็น Seed เพื่อสร้าง Ed25519 public/private key ด้วย Libsodium โดย Keypair นี้จะใช้เพื่อทำการ Sign และ Verify signature

จากนั้นเพื่อจะทำการ Register กับ Server, Client จะทำการส่งข้อมูลต่างๆเหล่านี้

  • Your name
  • Your email address (account key)
  • The random 16-byte salt used to derive your signing key
  • The public key ที่ได้จาก Ed25519 Keypair

ขั้นตอนการ Authentication

Client จะทำการ Authentication ด้วยการส่ง email address และ request authentication challenge ไปยัง Server

จากนั้น Server จะทำการหา Account ด้วย email address ที่ให้มา พร้อมกับส่ง original 16-byte salt ที่ได้จากขั้นตอนการ Register พร้อมกับ random 32-byte challenge nonce ส่งกลับไป

Nonce นี้จะโดนเก็บไว้ที่ฝั่ง Server เพื่อใช้ในการ Authentication challenge ได้เพียงครั้งเดียว เมื่อ challenge fail จะต้องสร้าง challenge ใหม่

Client จะใช้ Salt และ Password และสร้าง Static key ใหม่ (ด้วยการใช้ 1000 รอบ PBKDF2 เหมือนขั้นตอนแรก) เพื่อให้ได้ Key ตัวเดิมที่เหมือนกับขั้นตอนการ Register และใช้เป็น seed เพื่อสร้าง Keypair ด้วย Ed25519 ให้ได้ Keypair ตัวเดิมที่เหมือนกับขั้นตอน Register อีกเช่นกัน

กระบวนการนี้จะเหมือนกับขั้นตอนการ Register ทั้งหมด เพื่อให้เราได้ Keypair ตัวเดิมกลับมาใช้งาน

ในขั้นตอนนี้หากเราใช้ Mobile Device ที่มี Secure Storage ก็อาจจะเอา Private Key ที่ได้จากรอบแรกไปเก็บไว้ได้

จากนั้น Client จะใช้ Private key ทำการ Sign nonce ที่ได้จาก Server และส่งข้อมูลต่อไปนี้กลับไปที่ Server

  • Your email address
  • The nonce that was signed*
  • Your signature on the nonce

Server ที่เก็บค่า Public key ไว้อยู่ จะทำการ Verify signature ของ Nonce ที่ได้รับ หากถูก ก็จะสร้าง secure session ขึ้นมาให้

ถ้าหาก Mobile Application เรามี Secure Storage ที่สามารถเรียกใช้งานได้จาก Biometric API หรือ FaceID. เช่น Android มี BiometricPrompt* ละมี CryptoObject IdentityCredential หรือ iOS ที่สามารถใช้ Biometry-protected entries in iOS keychain* ที่สามารถ เก็บ Private key ไว้ได้ เราก็สามารถใช้ Key pair ดังกล่าวแทนได้เลย

--

--