เจาะลึกการยืนยันผู้ใช้

เอกสารนี้อธิบายว่า userVerification คืออะไรใน WebAuthn และลักษณะการทํางานของเบราว์เซอร์ที่เกิดขึ้นเมื่อระบุ userVerification ในระหว่างการสร้างหรือการตรวจสอบสิทธิ์พาสคีย์

โดยพาสคีย์สร้างขึ้นจากวิทยาการเข้ารหัสคีย์สาธารณะ การสร้างพาสคีย์จะสร้างคู่คีย์สาธารณะและส่วนตัว ผู้ให้บริการพาสคีย์จะจัดเก็บคีย์ส่วนตัว และระบบจะส่งคีย์สาธารณะไปยังเซิร์ฟเวอร์ของฝ่ายที่เชื่อถือ (RP) เพื่อจัดเก็บ เซิร์ฟเวอร์จะตรวจสอบสิทธิ์ผู้ใช้ได้โดยยืนยันลายเซ็นที่ลงนามด้วยพาสคีย์เดียวกันโดยใช้คีย์สาธารณะที่จับคู่ไว้ แฟล็ก "ผู้ใช้อยู่ด้วย" (UP) ในข้อมูลเข้าสู่ระบบด้วยคีย์สาธารณะพิสูจน์ว่ามีคนโต้ตอบกับอุปกรณ์ระหว่างการตรวจสอบสิทธิ์

การยืนยันผู้ใช้เป็นการรักษาความปลอดภัยอีกชั้นหนึ่งซึ่งไม่บังคับ แต่จะยืนยันว่ามีบุคคลที่ถูกต้องอยู่ด้วยระหว่างการตรวจสอบสิทธิ์ ไม่ใช่แค่บุคคลใดบุคคลหนึ่งตามที่การยืนยันผู้ใช้ยืนยัน ในสมาร์ทโฟน การดำเนินการนี้มักจะทำโดยใช้กลไกการล็อกหน้าจอ ไม่ว่าจะเป็นข้อมูลไบโอเมตริก, PIN หรือรหัสผ่าน ระบบจะรายงานการดำเนินการยืนยันผู้ใช้ใน Flag "UV" ที่แสดงในข้อมูลโปรแกรมตรวจสอบสิทธิ์ระหว่างการลงทะเบียนและการตรวจสอบสิทธิ์พาสคีย์

ภาพหน้าจอของกล่องโต้ตอบการยืนยันผู้ใช้ในพวงกุญแจ iCloud บน macOS กล่องโต้ตอบจะแจ้งให้ผู้ใช้ลงชื่อเข้าใช้โดยใช้ Touch ID โดยแสดงต้นทางที่ขอการตรวจสอบสิทธิ์ รวมถึงชื่อผู้ใช้ ที่ด้านขวาบนของกล่องโต้ตอบจะมีปุ่ม "ยกเลิก"
กล่องโต้ตอบการยืนยันผู้ใช้ในพวงกุญแจ iCloud ใน macOS
ภาพหน้าจอของกล่องโต้ตอบการยืนยันผู้ใช้ใน Chrome สําหรับ Android กล่องโต้ตอบจะแจ้งให้ผู้ใช้ยืนยันตัวตนโดยใช้การจดจำใบหน้าหรือการตรวจจับลายนิ้วมือ และแสดงต้นทางที่ขอการตรวจสอบสิทธิ์ ที่ด้านซ้ายล่างจะมีตัวเลือกให้ยืนยันโดยใช้ PIN
กล่องโต้ตอบการยืนยันผู้ใช้ใน Chrome บน Android

มีการตรวจสอบ UP และ UV บนเซิร์ฟเวอร์อย่างไร

ระบบจะส่งสัญญาณ Flag แบบบูลีน "ผู้ใช้อยู่ (UP)" และ "ผู้ใช้ยืนยันแล้ว (UV)" ไปยังเซิร์ฟเวอร์ในช่องข้อมูลโปรแกรมตรวจสอบสิทธิ์ ในระหว่างการตรวจสอบสิทธิ์ เนื้อหาในช่องข้อมูล Authenticator จะตรวจสอบได้ด้วยการยืนยันลายเซ็นโดยใช้คีย์สาธารณะที่จัดเก็บไว้ ตราบใดที่ลายเซ็นถูกต้อง เซิร์ฟเวอร์จะถือว่าการแจ้งว่าไม่เหมาะสมดังกล่าวเป็นเรื่องจริง

ภาพโครงสร้างข้อมูลการตรวจสอบสิทธิ์ จากซ้ายไปขวา ส่วนต่างๆ ของโครงสร้างข้อมูลจะอ่านว่า "RP ID HASH" (32 ไบต์), "FLAGS" (1 ไบต์), "COUNTER" (4 ไบต์, uint32 แบบ Big-endian), "ATTESTE CRED. DATA" (ความยาวแบบแปรผันหากมี) และ "EXTENSIONS" (ความยาวแบบแปรผันหากมี (CBOR)) ส่วน "FLAGS" จะขยายเพื่อแสดงรายการ Flag ที่เป็นไปได้ โดยติดป้ายกำกับจากซ้ายไปขวาว่า "ED", "AT", "0", "BS", "BE", "UV", "0" และ "UP"
ช่องข้อมูล Authenticator ในข้อมูลเข้าสู่ระบบคีย์สาธารณะ

ในการลงทะเบียนและตรวจสอบสิทธิ์พาสคีย์ เซิร์ฟเวอร์ควรตรวจสอบว่า Flag UP เป็น true และ Flag UV เป็น true หรือ false ขึ้นอยู่กับข้อกำหนด

การระบุพารามิเตอร์ userVerification

ตามข้อกำหนด WebAuthn นั้น RP สามารถขอการยืนยันผู้ใช้ด้วยพารามิเตอร์ userVerification ทั้งในการสร้างและยืนยันข้อมูลเข้าสู่ระบบ ยอมรับ 'preferred', 'required' หรือ 'discouraged' ซึ่งหมายความว่า

  • 'preferred' (ค่าเริ่มต้น): ใช้วิธีการยืนยันผู้ใช้ในอุปกรณ์ก่อน แต่สามารถข้ามได้หากไม่พร้อมใช้งาน ข้อมูลเข้าสู่ระบบการตอบกลับมีค่าแฟล็ก UV เป็น true หากมีการยืนยันผู้ใช้ และ false หากไม่มีการดำเนินการ UV
  • 'required': ต้องเรียกใช้วิธีการยืนยันผู้ใช้ที่มีอยู่ในอุปกรณ์ หากไม่มี การส่งคำขอจะไม่สำเร็จ ซึ่งหมายความว่าข้อมูลเข้าสู่ระบบของคำตอบจะแสดงผลเสมอโดยตั้งค่า Flag UV เป็น true
  • 'discouraged': ไม่แนะนำให้ใช้วิธีการยืนยันผู้ใช้ อย่างไรก็ตาม ระบบอาจดำเนินการยืนยันผู้ใช้อยู่ดี และ Flag UV อาจมีค่าเป็น true หรือ false ทั้งนี้ขึ้นอยู่กับอุปกรณ์

ตัวอย่างโค้ดสำหรับการสร้างพาสคีย์

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

โค้ดตัวอย่างสำหรับการตรวจสอบสิทธิ์พาสคีย์

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

คุณควรเลือกตัวเลือกใดสำหรับ userVerification

ค่า userVerification ที่คุณควรใช้ขึ้นอยู่กับข้อกําหนดของแอปพลิเคชัน รวมถึงความต้องการด้านประสบการณ์ของผู้ใช้

กรณีที่ควรใช้userVerification='preferred'

ใช้ userVerification='preferred' หากคุณให้ความสำคัญกับประสบการณ์ของผู้ใช้มากกว่าการปกป้อง

สภาพแวดล้อมบางอย่างทำให้การตรวจสอบผู้ใช้ทำให้เกิดปัญหามากกว่าการปกป้อง เช่น ใน macOS ที่ใช้ Touch ID ไม่ได้ (เนื่องจากอุปกรณ์ไม่รองรับ มีการปิดใช้ หรืออุปกรณ์อยู่ในโหมดฝาพับ) ระบบจะขอให้ผู้ใช้ป้อนรหัสผ่านระบบแทน ซึ่งทำให้เกิดความไม่สะดวกและผู้ใช้อาจเลิกตรวจสอบสิทธิ์ไปเลย หากการขจัดอุปสรรคสำคัญกว่าสำหรับคุณ ให้ใช้ userVerification='preferred'

ภาพหน้าจอของกล่องโต้ตอบพาสคีย์ใน macOS ที่ปรากฏขึ้นเมื่อ Touch ID ไม่พร้อมใช้งาน กล่องโต้ตอบจะมีข้อมูล เช่น ต้นทางที่ขอการตรวจสอบสิทธิ์ รวมถึงชื่อผู้ใช้ ที่ด้านบนขวาของกล่องโต้ตอบจะมีปุ่มที่มีป้ายกำกับว่า "ยกเลิก"
กล่องโต้ตอบพาสคีย์ที่แสดงใน macOS เมื่อ Touch ID ไม่พร้อมใช้งาน

เมื่อใช้ userVerification='preferred' ธง UV จะเป็น true หากยืนยันผู้ใช้สำเร็จ และ false หากข้ามการยืนยันผู้ใช้ ตัวอย่างเช่น ใน macOS ที่ไม่มี Touch ID ระบบจะขอให้ผู้ใช้คลิกปุ่มเพื่อข้ามการยืนยันผู้ใช้ และข้อมูลเข้าสู่ระบบคีย์สาธารณะจะมี Flag false UV

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

กรณีที่ควรใช้userVerification='required'

ใช้ userVerification='required' หากคิดว่าทั้ง UP และ UV จำเป็นอย่างยิ่ง

ข้อเสียของตัวเลือกนี้คือผู้ใช้อาจพบปัญหามากขึ้นเมื่อลงชื่อเข้าใช้ ตัวอย่างเช่น ใน macOS ที่ไม่มี Touch ID ระบบจะขอให้ผู้ใช้ป้อนรหัสผ่านระบบ

userVerification='required' ช่วยให้มีการยืนยันผู้ใช้ในอุปกรณ์ได้ ตรวจสอบว่าเซิร์ฟเวอร์ยืนยันแล้วว่า Flag UV คือ true

บทสรุป

การใช้การยืนยันผู้ใช้ช่วยให้ฝ่ายที่เชื่อถือพาสคีย์สามารถประเมินความเป็นไปได้ที่เจ้าของอุปกรณ์จะลงชื่อเข้าใช้ได้ โดยนักพัฒนาแอปสามารถเลือกได้ว่าจะกำหนดให้ต้องมีการยืนยันผู้ใช้หรือไม่ หรือจะกำหนดให้ผู้ใช้ยืนยันหรือไม่ก็ได้ ทั้งนี้ขึ้นอยู่กับว่ากลไกการลงชื่อเข้าใช้สำรองส่งผลต่อขั้นตอนของผู้ใช้มากน้อยเพียงใด ตรวจสอบว่าเซิร์ฟเวอร์ตรวจสอบ Flag UP และ Flag UV สำหรับการตรวจสอบสิทธิ์ผู้ใช้ด้วยพาสคีย์