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

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

"การยืนยันผู้ใช้" คืออะไร ใน WebAuthn ไหม

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

บทสรุป

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