การแฮชรหัสผ่านทางฝั่งไคลเอ็นต์นั้นคุ้มค่าหรือไม่


132

เมื่อฉันต้องการวางระบบล็อกอินฉันมักจะเปรียบเทียบ MD5 ของรหัสผ่านที่กำหนดกับค่าในตารางผู้ใช้ทางฝั่งเซิร์ฟเวอร์

อย่างไรก็ตามเพื่อนของฉันคนหนึ่งบอกฉันว่ารหัสผ่านที่ "ชัดเจน" อาจถูกใช้โดยซอฟต์แวร์เครือข่าย

ดังนั้นคำถามของฉันคือ: ควรแฮชรหัสผ่านทางฝั่งไคลเอ็นต์หรือไม่? มันดีกว่าการแฮชที่ฝั่งเซิร์ฟเวอร์หรือไม่?


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

1
เพื่อความสมบูรณ์เนื่องจากเรากำลังพูดถึงความปลอดภัยและ MD5 ได้รับการกล่าวถึงใน OP: ควรใช้ Salt เสมอเมื่อเข้ารหัสรหัสผ่าน การใช้ MD5 แบบธรรมดาที่ไม่ใส่เกลือนั้นดีกว่าการจัดเก็บรหัสผ่านข้อความธรรมดาในฐานข้อมูลของคุณเพียงเล็กน้อย
sffc

1
@Cyclone การแฮชเฉพาะที่ฝั่งไคลเอ็นต์นั้นเป็นความคิดที่ไม่ดีอย่างแน่นอนเนื่องจากหากผู้โจมตีรู้จักแฮชเขาก็สามารถใช้มันเพื่อเข้าสู่ระบบราวกับว่าเขารู้รหัสผ่านโดยข้ามรหัสการแฮชฝั่งไคลเอ็นต์
Teejay

5
@Teejay: นั่นคือเหตุผลที่คุณไม่ส่งแฮชในที่ชัดเจน เซิร์ฟเวอร์ส่งเกลือแบบสุ่มไปยังไคลเอนต์คุณต่อท้ายแฮชรหัสผ่านและแฮชข้อมูลทั้งหมดอีกครั้งจากนั้นส่งกลับไปที่เซิร์ฟเวอร์ซึ่งทำการคำนวณแบบเดียวกัน การโจมตีซ้ำล้มเหลวเนื่องจากเกลือจะแตกต่างกัน
MSalters

2
คำถามนี้ควรอยู่ที่ security.stackexchange.com ไม่ใช่หรือ?
efr4k

คำตอบ:


115

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

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

บนเซิร์ฟเวอร์:

  • สร้างบิตสุ่ม
  • ส่งบิตเหล่านี้ (เป็นข้อความที่ชัดเจน) ไปยังไคลเอนต์

ในไคลเอนต์:

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

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

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


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

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

3
@ เดิร์กเนื่องจากผู้โจมตีสามารถดมได้ทั้งสองวิธี "บิตสุ่ม" จะถูกดมกลิ่นไปด้วย จากนั้นผู้โจมตีสามารถวิเคราะห์ (อ่าน: brute force) คู่การร้องขอและการตอบสนองแบบออฟไลน์เพื่อค้นหารหัสผ่านเดิม
Pacerier

7
อย่างไรก็ตามเพื่อจุดประสงค์ในการส่งรหัสผ่านหรือแฮชของรหัสผ่านมักใช้กระบวนการที่ไม่สมมาตรเช่น Diffie-Hellman เพื่อสร้างคีย์การเข้ารหัสที่อนุญาตให้ทั้งสองฝ่ายแลกเปลี่ยนข้อมูลโดยที่ฝ่ายสอดแนมไม่สามารถถอดรหัสได้ นี่คือสิ่งที่ SSL ทำและเป็นเหตุผลที่ไซต์ส่วนใหญ่มีหน้าเข้าสู่ระบบบน HTTPS / SSL SSL ป้องกันการโจมตีซ้ำแล้ว ฉันอยากจะแนะนำให้ใช้ SSL แทนการสร้างโปรโตคอลของคุณเอง แม้ว่าฉันจะเห็นด้วยกับ salting + แฮชฝั่งไคลเอนต์รหัสผ่าน แต่ส่งสิ่งเหล่านี้ผ่านการเชื่อมต่อ SSL ที่กำหนด
AaronLS

14
เพื่อความชัดเจน: หากคุณไม่ได้ใช้ HTTPS ไม่สำคัญว่าคุณจะเรียกใช้จาวาสคริปต์ใดบนไคลเอนต์ MITM จะสามารถแก้ไขเนื้อหาของเพจของคุณก่อนที่จะเข้าถึงลูกค้า HTTPS เป็นทางออกเดียว
aidan

60

ประการแรกสิ่งนี้ไม่ได้ปรับปรุงความปลอดภัยของแอปพลิเคชันของคุณ (สมมติว่าเป็นเว็บแอป)

ใช้ SSL (หรือจริง ๆ แล้ว TLS ซึ่งโดยทั่วไปเรียกว่า SSL) ไม่แพงจริงๆ (วัดเวลาที่คุณใช้เพื่อค้นหาวิธีรอบ ๆ และคูณด้วยค่าแรงขั้นต่ำการซื้อใบรับรองจะชนะเกือบตลอดเวลา)

เหตุผลนี้เป็นเรื่องง่าย TLS ช่วยแก้ปัญหา (เมื่อใช้กับใบรับรองที่ซื้อแล้วไม่ได้ลงนามด้วยตนเอง) ซึ่งมีขนาดค่อนข้างใหญ่ในการเข้ารหัส: ฉันจะรู้ได้อย่างไรว่าเซิร์ฟเวอร์ที่ฉันกำลังพูดถึงคือเซิร์ฟเวอร์ที่ฉันคิดว่ากำลังคุยอยู่ ใบรับรอง TLS เป็นวิธีการพูดว่า: "ฉันซึ่งเป็นผู้ออกใบรับรองซึ่งได้รับความไว้วางใจจากเบราว์เซอร์ของคุณรับรองว่าเว็บไซต์ที่ [url] มีคีย์สาธารณะนี้พร้อมด้วยคีย์ส่วนตัวที่เกี่ยวข้องซึ่ง (คีย์ส่วนตัว) มีเพียงเซิร์ฟเวอร์เท่านั้นที่รู้ ฉันเซ็นลายเซ็นของฉันทั่วทั้งเอกสารหากใครแก้ไขลายเซ็นคุณสามารถดูได้ "

หากไม่มี TLS การเข้ารหัสใด ๆ ก็ไร้จุดหมายเพราะถ้าฉันนั่งข้างๆคุณในร้านกาแฟฉันสามารถทำให้แล็ปท็อป / สมาร์ทโฟนของคุณคิดว่าฉันเป็นเซิร์ฟเวอร์และ MiTM (Man in The Middle) คุณ ด้วย TLS แล็ปท็อป / สมาร์ทโฟนของคุณจะกรีดร้องว่า "UNTRUSTED CONNECTION" เพราะฉันไม่มีใบรับรองที่ลงนามโดยผู้ออกใบรับรองที่ตรงกับไซต์ของคุณ (การเข้ารหัสเทียบกับการพิสูจน์ตัวตน)

Disclaimer: ผู้ใช้มักจะคลิกขวาผ่านคำเตือนเหล่านี้: "การเชื่อมต่อที่ไม่น่าเชื่อถืออะไรนะฉันแค่อยากได้รูปลูกแมวของฉัน! เพิ่มข้อยกเว้น คลิก ยืนยัน คลิก YAY! ลูกแมว!"

อย่างไรก็ตามหากคุณไม่ต้องการซื้อใบรับรองจริงๆให้ใช้การแฮชจาวาสคริปต์ฝั่งไคลเอ็นต์ (และใช้ไลบรารีสแตนด์ฟอร์ด (SJCL) สำหรับสิ่งนั้นอย่าใช้CRYPTO ด้วยตัวคุณเอง )

ทำไม? ใช้รหัสผ่านซ้ำ! ฉันสามารถขโมยคุกกี้เซสชันของคุณ (ซึ่งทำให้ฉันสามารถแกล้งเซิร์ฟเวอร์ของคุณว่าฉันเป็นคุณ) โดยไม่ใช้ HTTPS ได้อย่างง่ายดาย (ดู firesheep) อย่างไรก็ตามหากคุณเพิ่มจาวาสคริปต์ในหน้าเข้าสู่ระบบของคุณซึ่งก่อนที่จะส่งให้แฮชรหัสผ่านของคุณ (ใช้ SHA256 หรือดีกว่านั้นให้ใช้ SHA256 ส่งคีย์สาธารณะที่คุณสร้างขึ้นจากนั้นเข้ารหัสแฮชรหัสผ่านด้วยสิ่งนั้นคุณจะไม่สามารถใช้เกลือได้ ด้วยสิ่งนี้) จากนั้นส่งรหัสผ่านที่แฮช / เข้ารหัสไปยังเซิร์ฟเวอร์ ล้างแฮชบนเซิร์ฟเวอร์ของคุณด้วยเกลือและเปรียบเทียบกับสิ่งที่เก็บไว้ในฐานข้อมูลของคุณ (เก็บรหัสผ่านดังนี้:

(SHA256(SHA256(password)+salt))

(บันทึกเกลือเป็นข้อความธรรมดาในฐานข้อมูลด้วย)) และส่งรหัสผ่านของคุณดังนี้:

RSA_With_Public_Key(SHA256(password))

และตรวจสอบรหัสผ่านของคุณดังนี้:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

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


ฉันคิดว่านี่เป็นคำตอบที่ดี แต่อาจต้องการข้อมูลเพิ่มเติมเกี่ยวกับวิธีการเกลืออย่างถูกต้องและควรใช้ฟังก์ชันแฮช "ช้า" ก่อนที่จะจัดเก็บรหัสผ่านบนเซิร์ฟเวอร์ (เช่น bcrypt)
Neyt

24

คุณน่าจะโอเคไม่ต้องกังวลเรื่องนี้ - ตามที่ Dirk กล่าวถึงแม้ว่าคุณจะแฮชรหัสผ่านผู้ใช้ที่เป็นอันตรายอาจอยู่ในเครือข่ายและเห็นว่ามีการส่งแฮชและสามารถส่งแฮชเดียวกันได้เอง

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

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


แก้ไข ส.ค. 2014: Google กำลังผลักดันให้เว็บไซต์เปลี่ยนไปใช้ HTTPS ทุกที่อย่างมากขึ้นเรื่อย ๆเนื่องจากการรักษาความปลอดภัยของการสื่อสารเป็นวิธีเดียวที่จะป้องกันการโจมตีจากการดมกลิ่นของเครือข่าย ความพยายามในการทำให้ข้อมูลที่ส่งนั้นสับสนจะขัดขวางไม่หยุดยั้งผู้โจมตีโดยเฉพาะและอาจทำให้นักพัฒนารู้สึกถึงความปลอดภัยที่ผิดพลาดที่เป็นอันตรายได้


ผมคิดว่าความคิดเห็นของคุณที่ clientside คร่ำเครียดเป็นเพียง "ดีขึ้นเล็กน้อย" เป็นจริงถ้าคุณกำลังแต่เพียงผู้เดียวที่เน้นการรับxรหัสผ่านของผู้ใช้และการเข้าถึงบริการเดียว ถ้าคุณพิจารณาถึงผลรวมฉันจะบอกว่า "ดีกว่ามาก"; เนื่องจากจะป้องกันไม่ให้สร้างฐานข้อมูลการค้นหารหัสผ่านขนาดใหญ่ที่ใช้ในการกำจัดแฮชเค็มในบริการต่างๆ IMO ดูว่า AWS Cognito ทำอะไรในไคลเอนต์เพื่อเป็นข้อมูลอ้างอิง
f1lt3r

17

อันที่จริงฉันไม่เห็นด้วยที่การแฮชฝั่งไคลเอ็นต์มีความปลอดภัยมากกว่าในกรณีนี้ ฉันคิดว่ามันปลอดภัยน้อยกว่า

จุดทั้งหมดของการจัดเก็บแฮชของรหัสผ่านในฐานข้อมูลของคุณเมื่อเทียบกับรหัสผ่านจริง (หรือแม้แต่รหัสผ่านที่เข้ารหัส) ก็คือเป็นไปไม่ได้ในทางคณิตศาสตร์ที่จะได้รับรหัสผ่านดั้งเดิมจากแฮช (แม้ว่าในทางทฤษฎีจะเป็นไปได้ที่จะได้รับการชนกันก็ตาม อินพุตแฮชซึ่งความยากขึ้นอยู่กับความปลอดภัยของอัลกอริทึมการแฮช) เวกเตอร์การโจมตีที่เป็นไปได้ที่นี่คือหากผู้โจมตีที่อาจเกิดขึ้นได้บุกรุกฐานข้อมูลที่เก็บรหัสผ่านของคุณเขา / เธอจะยังไม่สามารถรับรหัสผ่านเดิมของผู้ใช้ของคุณได้

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

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

อย่างไรก็ตามคำถามประเภทนี้อาจได้รับคำตอบจากผู้เชี่ยวชาญมากกว่าใน Security StackExchange


3
เห็นด้วยอย่างยิ่งกับเรื่องนี้ สำหรับวิธีการทำงานของฝั่งไคลเอ็นต์เราจะต้องส่งเกลือไปให้ลูกค้าด้วยซึ่งจะทำให้วัตถุประสงค์ทั้งหมดของการทำเกลือเป็นโมฆะ!
James Wright

@JamesWright: ประเด็นคือการส่งเกลือแบบสุ่มสำหรับการใช้งานแต่ละครั้งซึ่งป้องกันการนำข้อความเข้าสู่ระบบมาใช้ซ้ำอย่างผิดกฎหมาย (รูปแบบของการโจมตีซ้ำ) การส่งเกลือเท่าเดิมทุกครั้งไม่มีจุดหมายแน่นอน
MSalters

สิ่งที่คุณต้องทำคือใช้ "nonce" ( en.wikipedia.org/wiki/Cryptographic_nonce ) ด้วยวิธีนี้เซิร์ฟเวอร์ยังควบคุมเกลือและทำให้สิ่งนี้ปลอดภัย การแฮชในฝั่งไคลเอ็นต์ก็มีความสำคัญเช่นกันเพื่อให้โค้ด JS ที่ฉีดเข้าไปไม่สามารถค้นหาได้ง่ายในภายหลัง เพิ่มเติมที่นี่: stackoverflow.com/a/21716654/43615
Thomas Tempelmann

สำหรับการใช้ salt + nonce ในกระบวนการตรวจสอบสิทธิ์การเข้าสู่ระบบโปรดดูคำตอบนี้: stackoverflow.com/a/24978909/43615
Thomas Tempelmann

เห็นได้ชัดว่าหากคุณแฮชในฝั่งไคลเอ็นต์คุณจะต้องแฮชอีกครั้งที่ฝั่งเซิร์ฟเวอร์เพื่อป้องกันไม่ให้จุดที่คุณกำลังทำอยู่ ตามที่คนอื่นชี้ให้เห็นเพื่อความเป็นส่วนตัวคุณต้องการเข้ารหัสฝั่งไคลเอ็นต์อยู่แล้ว
Daniel Methner

5

โปรดทราบว่าการรักษารหัสผ่านให้ปลอดภัยกับบุคคลที่สามนั้นไม่ใช่ทั้งหมดที่มี

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

ดังนั้นการแฮช / การเข้ารหัสฝั่งไคลเอ็นต์จึงสมเหตุสมผล


ตกลงกัน! คนพลาดจุดนี้เยอะมาก หากฉันดาวน์โหลดฐานข้อมูลรหัสผ่านของรหัสผ่านที่ถูกแฮชแบบเค็มและฉันสามารถถอดรหัสได้เพียงอันเดียวโดยใช้ฐานข้อมูลการค้นหาแฮชก็มีโอกาสที่ฉันจะถอดรหัสได้ทั้งหมด เมื่อฉันมีรหัสผ่านเดิม 50k ตอนนี้ฉันมีคีย์สำหรับxผู้ใช้nบริการที่เข้ารหัสบนเซิร์ฟเวอร์เท่านั้น หากแต่ละบริการแฮชรหัสผ่านโดยไม่ซ้ำกันก่อนที่จะออกจากไคลเอ็นต์ฐานข้อมูลขนาดใหญ่ของรหัสผ่านข้ามบริการจะมีขนาดเล็กลงมาก ตรวจสอบปริมาณการเข้าสู่ระบบ AWS ของคุณดูว่าพวกเขาทำอะไร มันน่าจะเป็นวัตสันที่รักของฉัน
f1lt3r


1

เมื่อเร็ว ๆ นี้ฉันได้ทำงานหลายอย่างเกี่ยวกับเรื่องนี้ IRL มีปัญหาสองประการเกี่ยวกับการเข้ารหัสแฮช / สมมาตรฝั่งไคลเอ็นต์ด้วยการฆ่าความคิดจริงๆ: 1. คุณต้องนำเกลือกลับไปที่เซิร์ฟเวอร์ SOMEHOW ... และเข้ารหัส ฝั่งไคลเอ็นต์คุณต้องใช้รหัสผ่าน ... ซึ่งผิดวัตถุประสงค์ 2. คุณเปิดเผยการใช้งานแฮชของคุณ (ไม่ใช่ข้อตกลงที่ใหญ่โตเนื่องจากไซต์ส่วนใหญ่ใช้หนึ่งใน 3 หรือ 4 การแฮชอัลกอส) ซึ่งทำให้การโจมตีง่ายขึ้น (เพราะต้องลองอย่างใดอย่างหนึ่งแทนที่จะเป็น n)

สิ่งที่ฉันไปในที่สุดคือการเข้ารหัสแบบไม่สมมาตรบนไคลเอนต์โดยใช้ OpenPGP.js หรือคล้ายกัน ... สิ่งนี้อาศัยคีย์ที่นำเข้าหรือฝั่งไคลเอ็นต์ที่สร้างขึ้นบนไคลเอนต์และเซิร์ฟเวอร์ที่ส่งคีย์สาธารณะ เฉพาะคีย์สาธารณะของไคลเอ็นต์เท่านั้นที่จะถูกส่งกลับไปยังเซิร์ฟเวอร์ สิ่งนี้ป้องกันการโจมตี MIM และปลอดภัยพอ ๆ กับอุปกรณ์ (ปัจจุบันฉันเก็บคีย์ส่วนตัวของไคลเอนต์ไว้โดยค่าเริ่มต้นใน localStore ซึ่งเป็นการสาธิต)

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

พื้นฐานของสิ่งนี้คือเพื่อให้ผู้คนสามารถสื่อสารได้อย่างปลอดภัยในกรณีที่ HTTPS ถูก จำกัด (เช่นอิหร่าน / เกาหลีเหนือ atc ... ) และเป็นเพียงการทดลองสนุก ๆ

ฉันไกลตั้งแต่แรกที่นึกถึงสิ่งนี้http://www.mailvelope.com/ใช้สิ่งนี้


1

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

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

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

ข้อมูลผู้ใช้จะถูกเข้ารหัสทางฝั่งเบราว์เซอร์ด้วย

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

ตัวอย่างเล็ก ๆ ของทั้งสองวิธีนี้อยู่ในบล็อกของฉัน http://glynrob.com/javascript/client-side-hashing-and-encryption/


1

เมื่อเร็ว ๆ นี้ทั้ง GitHub และ Twitter ประกาศว่ารหัสผ่านที่เก็บไว้ในบันทึกภายใน ฉันเคยเกิดเหตุการณ์นี้ขึ้นโดยไม่ได้ตั้งใจในรายงานข้อผิดพลาดและบันทึกอื่น ๆ ที่พบว่าพวกเขาเข้าสู่ Splunk เป็นต้นสำหรับ twitter หากรหัสผ่านของ Trump อยู่ในบันทึกนั้นอาจเป็นเรื่องใหญ่ที่ผู้ดูแลระบบจะ "เห็น" สำหรับไซต์อื่น ๆ อาจไม่เป็นเช่นนั้น เป็นเรื่องใหญ่เนื่องจากผู้ดูแลระบบไม่ได้ใช้ประโยชน์มากนัก ไม่ว่าผู้ดูแลระบบจะไม่ชอบเห็นรหัสผ่านก็ตาม

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

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

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

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

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


ตรงกับความกังวลของฉัน หากเซิร์ฟเวอร์บันทึกโดยบังเอิญเนื่องจากการใช้งานที่ไม่ดีหรือมีเจตนาที่เป็นอันตรายอาจเป็นไปได้ว่าบัญชีอื่นของผู้ใช้อาจถูกบุกรุกได้หากพวกเขาใช้รหัสผ่านซ้ำ
Dan

0

พิจารณาสิ่งนี้:-

ลูกค้าส่งคำขอไปยังเซิร์ฟเวอร์ "ฉันมีรหัสผ่านเพื่อตรวจสอบ"

เซิร์ฟเวอร์ส่งสตริงสุ่มแบบครั้งเดียวเท่านั้น R $

ลูกค้าฝังรหัสผ่านของผู้ใช้ในสตริงนี้ (ตามกฎ (ตัวแปร) ที่คุณต้องการใช้)

ไคลเอนต์ส่งสตริงไปยังเซิร์ฟเวอร์และถ้ารหัสผ่านตกลงเซิร์ฟเวอร์จะล็อกผู้ใช้เข้า

หากเซิร์ฟเวอร์ได้รับคำขอเข้าสู่ระบบอื่นโดยใช้ R $ ผู้ใช้จะออกจากระบบและบัญชีถูกแช่แข็งอยู่ระหว่างการตรวจสอบ

เห็นได้ชัดว่ามาตรการรักษาความปลอดภัยอื่น ๆ (ปกติ) จะถูกนำมาใช้


0

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.