ขออนุญาตตั้งกระทู้ใหม่นะค่ะ
รบกวนปรึกษาแนวคิดหน่อยค่ะ ในการส่ง username + password ไปให้ API วิธีไหนปลอดภัยกว่ากัน
ทั้ง Client และ API เข้าผ่าน protocal https ตามคำแนะนำของกระทู้ก่อนหน้าค่ะ
1. ส่งไปเป็น Plain text ให้ API
2. เข้ารหัส Password แล้วส่งไปให้ API แล้วก็ถอดรหัสจะได้ Password แบบ Plain text แล้วเอาไปเช็ค Hash
3. เข้ารหัส Hash ก่อน แล้วค่อยส่งไปให้ API
พี่ๆใช่แบบไหนกันค่ะ
นอกจากผ่าน https แล้ว ผมจะเอา password ไป hash โดยผสม timestamp กับ salt เข้าไปด้วยครับ
ถ้าเอา password + timestamp ไป hash บน client แล้วส่งไปเช็คได้นี่ ฝั่ง server ก็ต้องเก็บ password เป็น plaintext ไว้เลยเหรอครับ?
ไม่จำเป็นครับ
แล้วทำยังไงครับนั่น ส่ง salt จาก server ไปให้ client คำนวณ hash?
hash มัน reverse ไม่ได้ แต่สามารถตรวจเปรียบเทียบ (validate) ได้ครับ
client ส่ง hash ไป ส่วน server ก็เก็บค่า hash ไว้ตั้งแต่สร้าง username + password แล้วเอามาเทียบกันครับ
ใน php ใช้ hash_equals เพื่อเทียบครับ
จริงๆ wordpress ก็ใช้วิธีนี้นะ
แต่ถ้ามี timestamp อยู่ในข้อความก่อน hash นี่ทำยังไงครับ?
wordpress ก็ใส่เข้าไปใน hash นะครับ แต่ไม่ใช่ด้วยการ concat นะ ถ้า concat เข้าไปที่ hash ตรงๆ นี่เบิดคำสิเว่า
ลองดูที่บรรทัด 660 ครับ
ผมไม่แน่ใจว่าโค้ดนั่นทำงานที่ฝั่งไหนนะครับ (อ่านผ่านๆ)
ที่นี้เงื่อนไขที่ด้านบนแจ้งผมมาคือเอา password ไปผสม salt และ timestamp ก่อนส่งไปที่ server แต่ว่าจะไม่มีการส่ง salt จาก server ไปยัง client และไม่มีการเก็บ password plain text ด้วย ผมเลยไล่การทำงานไม่ถูกครับ - -"
ปกติการ hash รหัสผ่านจะมี salt ด้วย ซึ่งเป็นส่วนที่ทำให้ความปลอดภัยเพิ่มขึ้นโดยเฉพาะเมื่อฐานข้อมูลหลุดออกไปครับ หากใช้ข้อ 3 ถ้าเราจะให้ client hash รหัสผ่านได้ตรงกับในฐานข้อมูลนั่นหมายถึง client จะต้องรู้ salt ด้วยแล้วจะไม่ปลอดภัยเอา
ข้อ 1, 2 นี่ถ้านับจริงๆ ก็ไม่ใช่ plain text เปลือยๆ เสียทีเดียวครับเพราะมันเข้ารหัสด้วย HTTPS แล้ว แต่เท่าที่ผมลองส่องดู อย่าง blognone เองนี่เวลา login ก็ส่ง user password บน HTTPS ตรงๆ ไม่ได้เข้ารหัสซ้อนอีกชั้นนะครับ
ขอบคุณค่ะ ขอสอบถามเพิ่มนะค่ะ
คือเราทำ hash + salt อยู่แล้ว แต่เราเก็บ salt ไว้ในตารางเดียวกันเลยค่ะ ประมาณนี้
Table User
id, username, password, salt
เขาทำกันแบบนี้หรือป่าวนะ ขอถามเป็นความรู้ค่ะ
แต่ถ้าเก็บแบบนี้ database หลุด salt ก็ไปด้วยแน่เลย หรือว่าเขาจะเก็บแยกกันนะ
ตรงนี้ขอรบกวนท่านอื่นด้วยครับ ผมไม่เคยทำ ? โดยส่วนตัวทุกงานที่มีต้อง auth ผมใช้ Firebase Auth หมดเลย
https://crackstation.net/hashing-security.htm
ปกติจะเก็บบน DB อย่างง่ายแบบนี้
Table User
int id, varchar username, text password_hash
ขอเน้นเรื่อง https ด้วยนะครับ เพราะการส่ง plain text ผ่าน http นั้นไม่ปลอดภัย
ครับ ปกติก็เป็นแบบนั้นอยู่แล้วไม่ใช่เหรอครับ
ใช่ครับ ปกติต้องเป็นแบบนั้นอยู่แล้ว แต่ผมเน้นย้ำกับ จขกท. น่ะครับ เพราะเป็นประเด็นที่ จขกท. กังวล คือเรื่องความปลอดภัยและการเข้ารหัส
จำได้ว่าผมส่งแบบ plain text แต่เพิ่ม OTP และผ่าน https นี่แหละกระมัง
หลังจากนั้นถ้าเข้าระบบสำเร็จก็ได้ access token เข้าไปแทน และให้เปลี่ยน secret key ทุกสามสิบนาที ทั้งที่จริงน่าจะทำ Oauth แต่สติปัญญาผมมันน้อย(ไม่รู้ว่าจบ cs มาได้ยังไง งงจนถึงบัดนี้)
https://security.stackexchange.com/questions/63435/why-use-an-authentication-token-instead-of-the-username-password-per-request
อยากให้ปลอดภัยต้องเริ่มจาก Structure ครับ คือไปตั้ง Domain แล้ว Sign-in ด้วย Domain แล้วทำ OAuth
ถ้าเก็บบน Database ต้องเขียน Code แบบ Code-First อย่าใช้ Stored หรือ ฝัง SQL command select ไว้ใน code แยก hash แยก salt คนละ table วิธีตรวจสอบ password ให้เอา plain text ไป encode ก่อนแล้วค่อยส่งค่าเข้า API ใน API ไม่ต้อง decode password กลับมาเป็น plain text เอา ไอ้ที่ encode เละๆ นั่งแหละ เทียบกับ database แล้วค่อยสร้าง OAuth ตอบกลับไป
https://security.stackexchange.com/questions/63435/why-use-an-authentication-token-instead-of-the-username-password-per-request