การเข้ารหัส Marshmallow ทำงานอย่างไรในทางเทคนิค


14

ฉันเพิ่งติดตั้ง Marshmallow บน Nexus 5 ผ่านการอัปเดตที่ส่งมา ฉันสับสนเกี่ยวกับวิธีการทำงานของการเข้ารหัส ฉันมีความรู้ด้านเทคนิคที่ดีเกี่ยวกับการเข้ารหัสในคอมพิวเตอร์ ฉันต้องการรับความรู้แบบเดียวกันเกี่ยวกับ Android 6

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

คำถาม:

  • ในกรณีของการเข้ารหัสที่ไม่มี PIN คีย์ถอดรหัสจะมาจากที่ใด ฉันคิดว่ามันถูกเก็บไว้ในชิปคล้ายกับ TPM นี่ถูกต้องหรือไม่? ถ้าอย่างนั้นอะไรที่ทำให้แฮ็กเกอร์ร้องขอคีย์นี้จากชิป ตรวจสอบแฮชของเฟิร์มแวร์หรือไม่ มีอะไรอีกไหม รายละเอียดทางเทคนิคจะได้รับการชื่นชมมาก
  • ในกรณีของการเข้ารหัสด้วย PIN จะใช้ PIN เป็นโทเค็นพิเศษเพื่อเข้าถึงคีย์ถอดรหัสหรือไม่ หรือกระบวนการถอดรหัสทำงานเหมือนกันกับว่าไม่มี PIN

TL; DL คำตอบ:

คีย์ถอดรหัสถูกปลดล็อคด้วยสิ่งต่อไปนี้ทั้งหมด:

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

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

คำตอบ:


15

ฉันอ้างอิงจากคู่มือ Android ที่นี่แต่:

บันทึก:

แหล่งที่ฉันใช้ไม่เกี่ยวข้องโดยตรงกับ Marshmallow แต่เกี่ยวข้องกับ Lollipop และสูงกว่า

TL: DR

ฉันจะตอบคำถามของ OP ทันที รายละเอียดทางเทคนิคจะเป็นไปตาม

  1. คีย์เข้ารหัสเริ่มต้นมาจากแหล่งฮาร์ดแวร์ (ชิปคล้ายกับ TPM) และรหัสผ่านเริ่มต้นของ AOSP ที่กำหนดไว้default_passwordในcryptfs.cไฟล์ต้นฉบับดูด้านล่าง

  2. ใช่ไม่ใช่เฉพาะค่าเริ่มต้น แต่รหัสผ่านใด ๆ จะถูกสร้างขึ้นเป็นกุญแจและถูกเก็บไว้ในชิปที่คล้ายกับ TPM เรียกว่า TEE (ย่อมาจาก "Trusted Execution Environment" ดูรายละเอียดเพิ่มเติมด้านล่าง)

  3. แฮ็กเกอร์ที่มีการเข้าถึง UART / JTAG เพื่อเข้าถึงชิปบน SoC ของอุปกรณ์สามารถเข้าถึงคีย์ TEE ในทางเทคนิคหรือเคอร์เนลแบบกำหนดเองสามารถรั่วไหลข้อมูลนี้ไปยังแฮ็กเกอร์ เอเจนซี 3 ตัวอักษรบางตัวในทฤษฎีสมคบคิดอาจร่วมมือกับ OEM เพื่อรับเมล็ดที่ไม่ปลอดภัยเหล่านี้ที่ใช้ในอุปกรณ์การผลิต แต่ฉันจะไม่วางร้านค้าจำนวนมาก ดูรายละเอียดเพิ่มเติมในส่วนสุดท้ายของคำตอบนี้

สิ่งเดียวที่ทำให้แฮ็กเกอร์ไม่สามารถเข้าถึงกุญแจได้คือความพยายามอย่างเต็มที่ในการทำเช่นนั้น

  1. การตรวจสอบของกัญชา (Checksumming) เฟิร์ม (เรียกว่า"Boot ที่ตรวจสอบแล้ว"โดย Google) ในความเป็นจริงทำบนและเหนืออมยิ้มโดยค่าเริ่มต้น (และสามารถใช้ได้จาก JellyBean 4.3 เป็นต้นไป) dm-verityโดยเคอร์เนลโมดูลที่เรียกว่า อย่างไรก็ตามนี่เป็นอิสระจากสถานะการเข้ารหัส

ที่มา:คู่มือการรักษาความปลอดภัย AOSP ที่นี่

  1. เกี่ยวกับกระบวนการที่เกี่ยวข้องกับการถอดรหัสระบบด้วยรหัสผ่านที่กำหนดเองดูด้านล่าง ฉันจะบอกคุณที่นี่ว่ารหัสผ่านผู้ใช้มีส่วนร่วมในการสร้างและการใช้งานคีย์เข้ารหัส

ภาพรวม

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

คุณสามารถค้นหารหัสผ่านเริ่มต้นที่กำหนดในไฟล์cryptfs.cโครงการ Android Open Source

เมื่อผู้ใช้ตั้งค่า PIN / รหัสผ่านหรือรหัสผ่านบนอุปกรณ์เฉพาะคีย์ 128 บิตเท่านั้นที่จะถูกเข้ารหัสและจัดเก็บใหม่ (เช่นการเปลี่ยนแปลง PIN ของผู้ใช้ / รหัสผ่าน / รูปแบบไม่ทำให้เกิดการเข้ารหัสลับของพาร์ติชัน userdata อีกครั้ง)

การเริ่มต้นอุปกรณ์ที่เข้ารหัสด้วยการเข้ารหัสเริ่มต้น

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

  1. ตรวจจับการเข้ารหัส / ข้อมูลโดยไม่มีรหัสผ่าน

ตรวจสอบว่าอุปกรณ์ Android ได้รับการเข้ารหัสเพราะ / data ไม่สามารถติดตั้งและตั้งค่าสถานะหนึ่งencryptableหรือforceencryptตั้งค่า

voldกำหนดvold.decryptเป็นtrigger_default_encryptionซึ่งจะเริ่มdefaultcryptoบริการ trigger_default_encryptionตรวจสอบประเภทการเข้ารหัสเพื่อดูว่า / data เข้ารหัสด้วยหรือไม่ใช้รหัสผ่าน

  1. ถอดรหัส / ข้อมูล

สร้างdm-cryptอุปกรณ์ผ่านอุปกรณ์บล็อกเพื่อให้อุปกรณ์พร้อมใช้งาน

  1. เมานต์ / ข้อมูล

voldจากนั้นเมานต์พาร์ติชั่นข้อมูลจริง / ถอดรหัสลับแล้วเตรียมพาร์ติชันใหม่ ได้กำหนดสถานที่vold.post_fs_data_doneที่จะ0แล้วชุดที่จะvold.decrypt trigger_post_fs_dataสิ่งนี้ทำให้init.rcเรียกใช้post-fs-dataคำสั่ง พวกเขาจะสร้างไดเรกทอรีที่จำเป็นใด ๆ หรือการเชื่อมโยงและจากนั้นตั้งค่าไปvold.post_fs_data_done1

เมื่อvoldเห็น 1 ในทรัพย์สินที่จะกำหนดสถานที่ให้บริการไปที่:vold.decrypt trigger_restart_frameworkสิ่งนี้ทำให้init.rcการเริ่มบริการในคลาสmainอีกครั้งและเริ่มบริการในคลาส Late_start เป็นครั้งแรกนับตั้งแต่เริ่มระบบ

  1. เริ่มกรอบงาน

ขณะนี้เฟรมเวิร์กบู๊ตบริการทั้งหมดโดยใช้การถอดรหัส / ข้อมูลและระบบพร้อมใช้งาน

การเริ่มต้นอุปกรณ์ที่เข้ารหัสโดยไม่มีการเข้ารหัสเริ่มต้น

นี่คือสิ่งที่เกิดขึ้นเมื่อคุณบูทอุปกรณ์ที่เข้ารหัสซึ่งมีรหัสผ่านที่ตั้งไว้ รหัสผ่านของอุปกรณ์สามารถเป็นหมุดรูปแบบหรือรหัสผ่าน

  1. ตรวจจับอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน

ตรวจสอบว่าอุปกรณ์ Android ถูกเข้ารหัสเพราะตั้งค่าสถานะ ro.crypto.state = "encrypted"

voldตั้งค่าvold.decryptเป็นtrigger_restart_min_frameworkเพราะ / data ถูกเข้ารหัสด้วยรหัสผ่าน

  1. เมานต์ tmpfs

initชุดห้าคุณสมบัติเพื่อบันทึกตัวเลือกติดเบื้องต้นได้รับสำหรับ / init.rcข้อมูลที่มีค่าพารามิเตอร์ที่ส่งผ่านจาก voldใช้คุณสมบัติเหล่านี้เพื่อตั้งค่าการทำแผนที่ crypto:

ro.crypto.fs_type

ro.crypto.fs_real_blkdev

ro.crypto.fs_mnt_point

ro.crypto.fs_options

ro.crypto.fs_flags (หมายเลขฐานสิบหก 8 หลัก ASCII นำหน้าด้วย 0x)

  1. เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน

กรอบการเริ่มต้นขึ้นและเห็นว่ามีการตั้งค่าvold.decrypt trigger_restart_min_frameworkสิ่งนี้บอกถึงเฟรมเวิร์กว่ามันกำลังบูทบนtmpfs /dataดิสก์และจำเป็นต้องได้รับรหัสผ่านผู้ใช้

อย่างไรก็ตามอันดับแรกจำเป็นต้องตรวจสอบให้แน่ใจว่าดิสก์ได้รับการเข้ารหัสอย่างถูกต้อง มันจะส่งคำสั่งไปยังcryptfs cryptocomplete ส่งคืน 0 หากการเข้ารหัสเสร็จสมบูรณ์แล้ว -1 ในข้อผิดพลาดภายในหรือ -2 ถ้าการเข้ารหัสไม่สำเร็จ กำหนดสิ่งนี้โดยดูในเมทาดาทา crypto เพื่อหาค่าสถานะ หากตั้งค่าไว้กระบวนการเข้ารหัสจะถูกขัดจังหวะและไม่มีข้อมูลที่ใช้งานได้บนอุปกรณ์voldvoldvoldCRYPTO_ENCRYPTION_IN_PROGRESS

หากvoldส่งคืนข้อผิดพลาด UI ควรแสดงข้อความให้กับผู้ใช้เพื่อรีบูตและรีเซ็ตอุปกรณ์เป็นค่าเริ่มต้นจากโรงงานและให้ผู้ใช้กดปุ่มเพื่อดำเนินการดังกล่าว

  1. ถอดรหัสข้อมูลด้วยรหัสผ่าน

เมื่อcryptfs cryptocompleteสำเร็จเฟรมเวิร์กจะแสดง UI ที่ขอรหัสผ่านดิสก์ ตรวจสอบ UI รหัสผ่านโดยการส่งคำสั่งไปยังcryptfs checkpw voldหากรหัสผ่านนั้นถูกต้อง (ซึ่งถูกกำหนดโดยการติดตั้งการถอดรหัสสำเร็จ/dataที่ตำแหน่งชั่วคราวจากนั้นให้ถอนการติดตั้ง) vold จะบันทึกชื่อของอุปกรณ์บล็อกที่ถูกถอดรหัสในคุณสมบัติro.crypto.fs_crypto_blkdevและส่งคืนสถานะ 0 ไปยัง UI หากรหัสผ่านไม่ถูกต้องมันจะส่งคืน -1 ให้กับ UI

  1. หยุดกรอบ

ทำให้ UI ขึ้นกราฟิกบูตเข้ารหัสลับและเรียก Vold cryptfs restartกับคำสั่ง voldกำหนดสถานที่ให้บริการvold.decryptการtrigger_reset_mainซึ่งเป็นสาเหตุที่จะทำinit.rc class_reset mainสิ่งนี้จะหยุดบริการทั้งหมดในmainคลาสซึ่งอนุญาตให้tmpfs /dataยกเลิกการเมานท์

  1. เมานต์ / ข้อมูล

voldจากนั้นเมาท์/dataพาร์ติชั่นที่ถอดรหัสแล้วและเตรียมพาร์ติชั่นใหม่ (ซึ่งอาจไม่เคยเตรียมมาหากมันถูกเข้ารหัสด้วยตัวเลือกการลบซึ่งไม่รองรับในรีลีสแรก) ได้กำหนดสถานที่vold.post_fs_data_doneที่จะ0แล้วชุดที่จะvold.decrypt trigger_post_fs_dataนี่เป็นสาเหตุที่จะทำงานของมันinit.rc post-fs-data commandsพวกเขาจะสร้างไดเรกทอรีที่จำเป็นใด ๆ หรือการเชื่อมโยงและจากนั้นตั้งค่าไปvold.post_fs_data_done 1เมื่อvoldเห็น1ในทรัพย์สินที่จะกำหนดสถานที่ที่จะvold.decrypt trigger_restart_frameworkทำให้init.rcการเริ่มบริการในคลาสmainอีกครั้งและเริ่มบริการในคลาสlate_startเป็นครั้งแรกนับตั้งแต่เริ่มระบบ

  1. เริ่มกรอบเต็ม

ขณะนี้เฟรมเวิร์กบู๊ตบริการทั้งหมดโดยใช้ระบบไฟล์ถอดรหัส / ข้อมูลและระบบพร้อมใช้งานแล้ว

การจัดเก็บคีย์เข้ารหัส

คีย์เข้ารหัสถูกเก็บไว้ในเมทาดาทา crypto การสำรองข้อมูลฮาร์ดแวร์ดำเนินการโดยใช้ความสามารถในการลงชื่อ (TEE) ของ Trusted Execution Environment ก่อนหน้านี้เราเข้ารหัสคีย์หลักด้วยรหัสที่สร้างขึ้นโดยใช้scryptกับรหัสผ่านของผู้ใช้และเกลือที่เก็บไว้

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

  1. สร้างคีย์การเข้ารหัสดิสก์แบบสุ่มขนาด 16 ไบต์ (DEK) และเกลือขนาด 16 ไบต์
  2. นำscryptไปใช้กับรหัสผ่านผู้ใช้และเกลือเพื่อสร้างคีย์กลาง 32- ไบต์ 1 (IK1)
  3. ผัด IK1 ที่มีค่าศูนย์ไบต์เท่ากับขนาดของคีย์ส่วนตัวที่ผูกไว้กับฮาร์ดแวร์ (HBK) เราเจาะจงเป็น: 00 || IK1 || 00..00; หนึ่งศูนย์ไบต์, 32 IK1 ไบต์, 223 ศูนย์ไบต์
  4. ลงนามเบาะ IK1 ด้วย HBK เพื่อสร้าง IK2 256- ไบต์
  5. นำscryptไปใช้กับ IK2 และเกลือ (เกลือเดียวกับขั้นตอนที่ 2) เพื่อสร้าง IK3 ขนาด 32 ไบต์
  6. ใช้ 16 ไบต์แรกของ IK3 เป็น KEK และ 16 ไบต์สุดท้ายเป็น IV
  7. เข้ารหัส DEK ด้วย AES_CBC พร้อมคีย์ KEK และเวกเตอร์เริ่มต้น IV

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

@ David ที่อยู่นอกเหนือขอบเขตของคำถามนี้โปรดถามอีกคนหนึ่งเกี่ยวกับ Android Nougat
Tamoghna Chowdhury


ฉันจะถอดรหัสพาร์ติชัน DATA ในโหมดการกู้คืนได้อย่างไร ผ่าน init.recovery. <ro.hardware> .rc
Benny

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