การเข้ารหัส MySQL และการจัดการคีย์


10

ฉันกำลังพัฒนาระบบอินทราเน็ตเฉพาะที่ใน PHP / MySQL เพื่อจัดการข้อมูลลูกค้าของเรา ดูเหมือนว่าวิธีปฏิบัติที่ดีที่สุดคือการเข้ารหัสข้อมูลที่ละเอียดอ่อนบนเซิร์ฟเวอร์ MySQL ขณะที่กำลังป้อน

ฉันยังไม่ชัดเจนในสิ่งที่จะเป็นวิธีที่ดีที่สุดในการทำเช่นนี้ในขณะที่ยังมีข้อมูลที่สามารถเข้าถึงได้อย่างง่ายดาย

ดูเหมือนจะเป็นคำถามยากที่จะตอบ: คีย์ถูกเก็บไว้ที่ไหน จะปกป้องคีย์ได้อย่างไร หากคีย์ถูกเก็บไว้ในเครื่องของผู้ใช้แต่ละคนจะป้องกันได้อย่างไรหากใช้ประโยชน์จากเครื่อง หากคีย์ถูกใช้ประโยชน์จะเปลี่ยนคีย์ได้อย่างไร

หากคีย์ถูกเก็บไว้ในฐานข้อมูลจะป้องกันได้อย่างไร ผู้ใช้จะเข้าถึงได้อย่างไร?


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

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

คำตอบ:


9

ไม่มีคุณสมบัติ MySQL ในตัวสำหรับจัดการการตั้งค่าคีย์เข้ารหัสที่ซับซ้อน คุณจะต้องใช้ตรรกะการเข้ารหัสจำนวนมากในโค้ด PHP และ / หรือโค้ดเบราว์เซอร์ (javascript?) ของคุณเอง

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

  • สำหรับหนึ่งฉันสมมติว่าคุณมีกฎไฟร์วอลล์ป้องกันโฮสต์ MySQL / PHP กับการเข้าถึงใด ๆ จาก IP ลูกค้าระยะไกลไม่ได้รับการอนุมัติ หากฉันถูกต้องมันสมเหตุสมผลแล้วที่คุณจะกังวลเกี่ยวกับการโจมตีจากเวิร์กสเตชันของผู้ใช้ที่ถูกบุกรุก

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

เริ่มต้นจากสมมติฐานทั้งสองนั้นเราควรสรุปว่าภัยคุกคามที่เกี่ยวข้องเพียงสองข้อเท่านั้นคือ A) การเดารหัสผ่านที่โหดร้ายและ B) การพยายามฉีด SQL

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

ตอนนี้เรามาพูดถึงวิธีการเข้ารหัสฝั่งเซิร์ฟเวอร์ที่ใช้กับสถานการณ์เหล่านี้:

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

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

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

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


1
ว้าว! คำตอบที่น่าอัศจรรย์และทั่วถึง; ขอบคุณมาก. ในช่วงไม่กี่วันที่ผ่านมาฉันได้พิจารณาตัวเลือกบางอย่างแล้วและตัดสินใจลองใช้โซลูชันฝั่งไคลเอ็นต์ตามที่คุณแนะนำ โดยหลักการแล้วคีย์จะถูกเก็บไว้ใน thumb drive ที่จะถูกเมาท์ในขณะที่ผู้ใช้ทำงานกับระบบ (ความปลอดภัยทางกายภาพนั้นแน่นมาก) และคีย์ที่เก็บไว้ในหน่วยความจำเท่านั้นตราบใดที่เซสชันยังมีชีวิตอยู่ ความคิดที่ว่ากุญแจจะสามารถเข้าถึงได้เฉพาะกับระบบในช่วงเวลาทำงานเมื่อฉันอยู่ที่นั่นเพื่อตรวจสอบการจราจรและอื่น ๆ
stormdrain

2

คุณอาจต้องการดูezNcryptซึ่งใช้ ecryptfs การควบคุมการเข้าถึงและการจัดการคีย์เพื่อให้ความปลอดภัยและประสิทธิภาพสูงสำหรับการเข้ารหัส Linux ของฐานข้อมูล MySQL และกระบวนการอื่น ๆ ไม่ฉันไม่ได้ทำงานให้พวกเขา


2

คุณสามารถใช้ Scytale มันเป็นพร็อกซี่ NoSQL crypto สำหรับ DBMS ที่ทันสมัยและการใช้งานเว็บ รองรับการเข้ารหัสหลายผู้รับและกลุ่ม เต็มไปด้วยระบบเข้ารหัสที่แข็งแกร่ง RSA / AES นอกจากนี้ยังเป็นฟรีและโอเพนซอร์ส 100%

https://bitbucket.org/maximelabelle/scytale

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