สารบัญ:

ความปลอดภัยด้วย Arduino: Atec608a: 7 ขั้นตอน
ความปลอดภัยด้วย Arduino: Atec608a: 7 ขั้นตอน

วีดีโอ: ความปลอดภัยด้วย Arduino: Atec608a: 7 ขั้นตอน

วีดีโอ: ความปลอดภัยด้วย Arduino: Atec608a: 7 ขั้นตอน
วีดีโอ: Secure Boot with ATECC608A 2024, พฤศจิกายน
Anonim
ความปลอดภัยด้วย Arduino: Atec608a
ความปลอดภัยด้วย Arduino: Atec608a
ความปลอดภัยด้วย Arduino: Atec608a
ความปลอดภัยด้วย Arduino: Atec608a

หัวข้อ

สวัสดีทุกคน !

นี่เป็นบทความ Instructables แรกของฉัน ดังนั้นฉันหวังว่ามันจะน่าสนใจสำหรับทุกคน

ในบทความนี้ ผมจะอธิบายวิธีการใช้ไมโครชิปที่เรียกว่า "ATECC608A" ซึ่งมีเครื่องมือรักษาความปลอดภัยหลายตัว

ชิปนี้ได้รับการออกแบบโดย MicroChip และเป็นเวอร์ชันสุดท้ายของ "CryptoAuthentication Chip" ก่อนหน้าเวอร์ชันนี้มี "ATSHA204A" และ "ATECC508A"

เหตุใดฉันจึงตัดสินใจใช้เวอร์ชันที่แล้วไม่ใช่เวอร์ชันก่อนหน้า

เวอร์ชันนี้เป็นชิปที่ล้ำหน้าที่สุดและมีฟังก์ชันที่เวอร์ชันเก่าไม่มี (เช่น โมดูล AES โมดูลป้องกัน IO …)

ทำไมถึงเป็นโครงการนี้ ?

ฉันทำงานในโดเมนของ CyberSecurity และในฐานะทุกคนที่ฉันรักการเขียนโปรแกรมและอุปกรณ์อิเล็กทรอนิกส์ ระหว่างการศึกษาของฉัน ฉันได้รับการประชุมกับผู้เชี่ยวชาญเกี่ยวกับ IoT Security ซึ่งแสดงให้เราเห็นว่า Industrial ไม่ได้ใช้ความปลอดภัยในวัตถุ IoT ของพวกเขา ฉันแสดงให้เราเห็นแม่กุญแจที่สามารถเปิดได้ด้วยสมาร์ทโฟนของคุณผ่านบลูทูธ บนแม่กุญแจ ประโยคหนึ่งบอกว่า "แม่กุญแจนี้ปลอดภัยที่สุดกว่าแม่กุญแจ !" ประโยคนี้ทำให้เขายิ้มและเขาแก้ไขประโยค "แม่กุญแจนี้เป็นแม่กุญแจที่แย่ที่สุดที่เคยสร้าง!"

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

หลังจากการสาธิตนี้ ฉันพยายามค้นหาโครงการโอเพ่นซอร์สที่เพิ่มเลเยอร์ความปลอดภัยให้กับวัตถุ IoT แต่ไม่พบเลย

ดังนั้นฉันจึงตัดสินใจทำงานในโปรเจ็กต์ที่ใช้เลเยอร์ความปลอดภัยสำหรับการสื่อสารระหว่างสองอ็อบเจ็กต์ IoT

ความคิดของฉันคืออะไร?

ระหว่างการสื่อสารระหว่างสอง IoT Object การโจมตีหลายครั้งสามารถเกิดขึ้นได้: Man Of the Mild, Copy of information และอื่นๆ.. ดังนั้นความคิดของฉันจึงง่ายมาก:

  1. การใช้ข้อมูลที่เข้ารหัสระหว่างออบเจ็กต์ IoT สองรายการขึ้นไป
  2. วัตถุดิบราคาถูก
  3. สามารถทำงานร่วมกับ Arduino UNO

ตอนนี้ผมจะอธิบายให้คุณฟังว่าผมนำภาพนามธรรมนี้ไปใช้กับ Arduino และชิป Atecc608a ได้อย่างไร ในบทความนี้ ผมจะอธิบายวิธีใช้ Arduino UNO กับ ATECC608A

ฉันจะเขียนบทความเกี่ยวกับการสื่อสารของสองวัตถุในครั้งต่อไป

เสบียง

คุณต้องการบางสิ่งสำหรับโครงการนี้:

  1. Arduino UNO หรือ MEGA (ชิปต้องเป็น Atmega 328 หรือ ATMEGA 2560)
  2. ชิป Atecc608A (ราคาตัวละน้อยกว่า 0.80$ หาง่ายบนเว็บไซต์ซัพพลายเออร์ของคุณ)
  3. อะแดปเตอร์ SOIC 8 พิน
  4. สายไฟและตัวต้านทานบางตัว

แผ่นข้อมูลของชิปรุ่นก่อนหน้า (Atecc508a) มีให้ที่นี่ -> แผ่นข้อมูล Atecc508a

ขั้นตอนที่ 1: ทีละขั้นตอน

เป็นขั้นเป็นตอน
เป็นขั้นเป็นตอน

ในบทความนี้ ฉันจะแสดงวิธีแก้ไขการกำหนดค่าของชิปนี้ และหลังจากวิธีเข้ารหัสข้อมูลโดยใช้อัลกอริทึม AES CBC

เราจะทำตามขั้นตอนเหล่านั้น:

  1. การออกแบบวงจร
  2. การกำหนดค่าชิปนี้
  3. การใช้โมดูล AES CBC
  4. ทำไมคุณถึงต้องใช้ชิปตัวนี้

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

Github ของฉัน: Github ของฉัน

ขั้นตอนที่ 2: คำเตือนเกี่ยวกับ Atec608a

คำเตือนเกี่ยวกับ Atec608a
คำเตือนเกี่ยวกับ Atec608a

ชิป Atec608a ไม่ใช่ชิปที่ "ง่าย"

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

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

ประการที่สาม ไลบรารีที่เขียนในภาษา C นั้นใหญ่และสมบูรณ์มาก ดังนั้น คุณต้องอ่านเอกสารของฟังก์ชันที่คุณจะใช้มาก่อน

ประการที่สี่ ไลบรารีที่เขียนขึ้นสำหรับชิปนี้ใช้ไม่ได้กับ Arduino UNO แต่ได้เพิ่มฟังก์ชันที่จำเป็นสำหรับการทำงานกับ Arduino UNO

ชิป ATECC608A

คุณสามารถสื่อสารกับชิปนี้โดย I2C ที่อยู่ของชิปนี้สามารถแก้ไขได้ในการกำหนดค่า

ชิปนี้มี 16 ช่องที่แตกต่างกันซึ่งสามารถบรรจุข้อมูลประเภทต่างๆ ได้:

  1. คีย์ ECC (ส่วนตัวหรือสาธารณะ)
  2. คีย์ AES
  3. ข้อมูลอื่นๆ (เช่น Sha hash หรือเพียงแค่คำพูด)

ในกรณีของเรา เราจะเก็บคีย์ AES ไว้ในช่องเดียว

ขั้นตอนที่ 3: 1. การออกแบบวงจร

1. การออกแบบวงจร
1. การออกแบบวงจร
1. การออกแบบวงจร
1. การออกแบบวงจร

1. การออกแบบวงจร

สคีมาของวงจรนี้ง่ายมาก!

คุณต้องใช้พลังงาน 3.3V เนื่องจากคำแนะนำอยู่ระหว่าง 2.0V ถึง 5.5V แต่ฉันชอบใช้ 3.3V

สำหรับชิปนี้ โดยปกติคุณมีจุดอยู่ที่มุมของชิป จุดนี้คือพิน 1 ของบอร์ดนี้ ฉันเพิ่มมุมมองด้านบนของ Atecc608a ด้วยหมายเลข PIN เนื่องจากเป็น 8-Lead SOIC ดังนั้นชิปจึงมีขนาดเล็กมาก

  1. ARDUINO 3.3V -> PIN 8 (Atecc608a)
  2. ARDUINO GND -> PIN 4 (Atecc608a)
  3. ARDUINO A4 (SDL) -> PIN 5 (Atecc608a)
  4. ARDUINO A5 (SCL) -> PIN 6 (Atecc608a)

คุณต้องใช้พลังงาน 3.3V เนื่องจากคำแนะนำอยู่ระหว่าง 2.0V ถึง 5.5V แต่ฉันชอบใช้ 3.3V

ฉันเพิ่มมุมมองด้านบนของ Atecc608a เนื่องจากเป็น 8-Lead SOIC ดังนั้นชิปจึงมีขนาดเล็กมาก หากคุณต้องการ ซัพพลายเออร์จึงสร้างบอร์ดโดยใช้ชิปบัดกรี มันอาจจะง่ายกว่าสำหรับคุณ

คำเตือน: ในกรณีของฉัน ฉันต้องเพิ่มตัวต้านทานระหว่าง SDA ของ Arduino และชิป (สำหรับ SDL ด้วย) ฉันเพิ่มตัวต้านทาน 4.7Kohm สำหรับแต่ละอัน

ขั้นตอนที่ 4: 2. การกำหนดค่าชิป (Atecc608a)

ก่อนใช้ฟังก์ชั่นการเข้ารหัสหรือถอดรหัส คุณต้องกำหนดค่าชิปก่อน ในขั้นตอนนี้ เราจะให้รายละเอียดทุกขั้นตอนที่คุณต้องทำสำหรับการกำหนดค่าชิปนี้

คำเตือน: ขั้นตอนนี้สำคัญมาก และหากคุณล็อกโซนก่อนสิ้นสุด คุณจะแก้ไขไม่ได้

ตามที่อธิบายไว้ก่อนหน้านี้ ชิปนี้มีสองโซน:

  1. Config Zone
  2. โซนข้อมูล

โซนการกำหนดค่ามีขนาด 128 ไบต์ แต่ไม่สามารถแก้ไขได้ 16 ไบต์แรก

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

  1. สร้างเทมเพลตการกำหนดค่า
  2. เขียนเทมเพลตนี้ไปที่ชิป
  3. ล็อค Config Zone
  4. เขียนคีย์ AES ของคุณ (128 บิต) ลงในช่อง
  5. ล็อคโซนข้อมูล

ข้อมูล

ด้านล่างฉันให้รายละเอียดแต่ละขั้นตอนของการกำหนดค่าด้วยโค้ดของฉัน แต่ไม่ต้องกังวล ฉันได้เพิ่มตัวอย่างการกำหนดค่าทั้งหมดใน Github ของฉัน ฉันใส่ความคิดเห็นในแต่ละฟังก์ชัน และไฟล์ *.ino จะพร้อมใช้งานในแต่ละขั้นตอนสำหรับคุณ

  • Github ของฉัน: Github ของฉัน
  • เส้นทางของการกำหนดค่าตัวอย่าง: configuration_example.ino

ขั้นตอนแรก: สร้างเทมเพลตการกำหนดค่า

ตามที่อธิบายไว้ก่อนหน้านี้ โซนการกำหนดค่าจะมีขนาด 128 บิต แต่ 16 บิตแรกไม่สามารถเปลี่ยนแปลงได้ โซนนี้ประกอบด้วยหลายส่วน แต่คุณจำเป็นต้องรู้เพียง 3 ส่วนของโซนการกำหนดค่านี้สำหรับโครงการนี้:

  1. ไบต์ 16 -> นี่คือที่อยู่ I2C ของชิป
  2. ไบต์ 20 ถึง 51 -> คุณสามารถแก้ไขประเภทของสล็อตสำหรับ 16 สล็อตของชิปนี้ได้ที่นี่
  3. ไบต์ 96 ถึง 127 -> คุณสามารถตั้งค่าประเภทของคีย์หรือข้อมูลที่ใช้ในแต่ละช่องได้ที่นี่

(หากต้องการคำอธิบายเพิ่มเติมของโซนนี้ทั้งหมด โปรดอ่านเอกสารประกอบ (หน้า 13 ส่วน 2.2))

ที่นี่ฉันใส่รายละเอียดแต่ละ Bytes/Parts ของ 112 ไบต์ของการกำหนดค่าชิป นี่คือตัวอย่าง แต่ละชิปที่ซื้อสามารถมีการกำหนดค่าที่แตกต่างกัน:

0xC0, // ที่อยู่ I2C

0x00, 0x00, 0x00, 0x83, 0x20, // กำหนดค่าสล็อต สล็อต 1 0x85, 0x20, // กำหนดค่าสล็อต สล็อต 2 0x8F, 0x20, // กำหนดค่าสล็อต สล็อต 3 0xC4, 0x8F, // สล็อตกำหนดค่าสล็อต 4 0x8F, 0x8F, // Slot Config Slot 5 0x8F, 0x8F, // Slot Config Slot 6 0x9F, 0x8F, // Slot Config Slot 7 0x0F, 0x0F, // Slot Config Slot 8 0x8F, 0x0F, // Slot Config Slot 9 0x8F, 0x0F, // Slot Config Slot 10 0x8F, 0x0F, // Slot Config Slot 11 0x8F, 0x0F, // Slot Config Slot 12 0x8F, 0x0F, // Slot Config Slot 13 0x00, 0x00, // Slot Config Slot 14 0x00, 0x00, // Slot Config Slot 15 0xAF, 0x8F, // Slot Config Slot 16 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x33, 0x00, // ช่องกำหนดค่าคีย์ 1 0x33, 0x00, // ช่องกำหนดค่าคีย์ 2 0x33, 0x00, // ช่องกำหนดค่าคีย์ 3 0x1C, 0x00, // ช่องกำหนดค่าคีย์ 4 0x1C, 0x00, // ช่องกำหนดค่าคีย์ 5 0x 1C, 0x00, // Key Config Slot 6 0x1C, 0x00, // Key Config Slot 7 0x3C, 0x00, // Key Config Slot 8 0x1A, 0x00, // Key Config Slot 9 0x3A, 0x00, // Key Config Slot 10 0x1A, 0x00, // Key Config Slot 11 0x3A, 0x00, // Key Config Slot 12 0x3A, 0x00, // Key Config Slot 13 0x3C, 0x00, // Key Config Slot 14 0x3C, 0x00, // Key Config Slot 15 0x1C, 0x00 // ช่องเสียบคีย์คอนฟิก 16

อย่างที่เห็น ฉันใส่ความคิดเห็นบางส่วนในโค้ดนี้เพื่อทำความเข้าใจการกำหนดค่านี้เพิ่มเติม

ในกรณีของคุณต้องเข้าใจเพียงสามสิ่ง:

  1. ไบต์ 16 -> นี่คือที่อยู่ I2C ของชิป
  2. ไบต์ 20 ถึง 51 -> คุณสามารถแก้ไขประเภทของสล็อตสำหรับ 16 สล็อตของชิปนี้ได้ที่นี่
  3. ไบต์ 96 ถึง 127 -> คุณสามารถตั้งค่าประเภทของคีย์หรือข้อมูลที่ใช้ในแต่ละช่องได้ที่นี่

ฉันจะไม่อธิบายประเภทของการกำหนดค่าและเหตุผลที่ฉันใช้สิ่งนี้และไม่ใช่การกำหนดค่าอื่น เพราะมันซับซ้อนในการอธิบายทุกอย่าง หากคุณต้องการข้อมูลเพิ่มเติม โปรดไปที่เอกสารประกอบ หน้า 16 ส่วน 2.2.1 สำหรับ "SlotConfig" และหน้า 19 ส่วน 2.2.5 สำหรับ "KeyConfig"

สำหรับตัวอย่างนี้ คุณจะใช้ช่อง 9 เพื่อจัดเก็บคีย์ AES

สำหรับสิ่งนี้เราจำเป็นต้องใส่ (หากต้องการคุณสามารถคัดลอกตัวอย่างด้านบนมีการแก้ไขในนั้น):

  1. ไบต์ 36 = 0x8F
  2. ไบต์ 37 = 0x0F
  3. ไบต์ 112 = 0x1A
  4. ไบต์ 113 = 0x00

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

  • สล็อตสามารถเขียนหรืออ่านได้ (การดำเนินการที่ชัดเจนหรือเข้ารหัส)
  • ประเภทของข้อมูลที่จัดเก็บ (คีย์ ECC, คีย์สาธารณะ, แฮช SHA, คีย์ AES …)
  • สล็อตสามารถล็อคได้
  • อนุญาตให้สร้างคีย์

เมื่อตั้งค่าไบต์ 36 และ 37 เป็น "0x0F8F":

  • ข้อมูลสามารถเขียนได้ใน Clear
  • เนื้อหาของสล็อตนี้เป็นความลับและไม่สามารถอ่านได้
  • ไม่สามารถใช้สล็อตสำหรับคำสั่ง CheckMac Copy

เมื่อตั้งค่าไบต์ 112 และ 113 เป็น "0x001A":

สล็อตสามารถจัดเก็บคีย์สมมาตร AES 128 บิตได้สูงสุดสี่คีย์ (KeyType = 0x6)

ขั้นตอนที่สอง: เขียนการกำหนดค่านี้

ขั้นตอนนี้สำคัญมากเพราะเราจะตั้งค่าชิปด้วยการกำหนดค่าของเรา และหากการกำหนดค่านี้ไม่ดี คุณจะใช้ชิปนี้

แต่ไม่ต้องกังวล ตราบใดที่การกำหนดค่าไม่ถูกล็อค คุณสามารถแก้ไขการกำหนดค่าของคุณได้

นี่คือรหัสที่ใช้ในการเขียนการกำหนดค่าไปยังชิป:

/** \brief เขียนการกำหนดค่าใหม่ไปยังชิป

* \param[ใน] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] config Array uint8_t ของการกำหนดค่า (ความยาว 112) * \param[in] len ขนาดของอาร์เรย์การกำหนดค่า * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นจะเป็นรหัสข้อผิดพลาด */ ATCA_STATUS write_configuration (ATCAIfaceCfg *cfg, uint8_t *config, size_t len) { if (len != 112) ส่งคืน ATCA_BAD_PARAM; สถานะ ATCA_STATUS; สถานะ = atcab_init(cfg); if (status == ATCA_SUCCESS) { // เขียนการกำหนดค่า Array ไปยังชิป // Padding ขนาด 16 ไบต์ (16 ไบต์แรกไม่สามารถเขียนได้) สถานะ = atcab_write_bytes_zone (ATCA_ZONE_CONFIG, 0, 16, (uint8_t *) config, len); สถานะการส่งคืน; } สถานะการส่งคืน; }

ฟังก์ชันนี้จะเขียนการกำหนดค่าของคุณในชิป

ขั้นตอนที่สาม: ล็อคการกำหนดค่า Zone

คำเตือน: โปรดใช้ความระมัดระวังในขั้นตอนนี้ หากคุณล็อกโซนนี้และการกำหนดค่าของคุณไม่ดี ชิปจะใช้ไม่ได้และคุณไม่สามารถแก้ไขโซนนี้ได้

สำหรับการดำเนินการนี้ เราจะใช้ฟังก์ชันนี้:

/** \brief ตรวจสอบว่า DATA_ZONE หรือ CONFIG_ZONE ถูกล็อคหรือไม่

* \param[ใน] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] โซน LOCK_ZONE_DATA หรือ LOCK_ZONE_CONFIG * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นจะเป็นรหัสข้อผิดพลาด */ ATCA_STATUS check_lock_zone (ATCAIfaceCfg *cfg, uint8_t โซน) { สถานะ ATCA_STATUS; บูลล็อค = เท็จ; ถ้า (โซน != (uint8_t)LOCK_ZONE_CONFIG && โซน != (uint8_t)LOCK_ZONE_DATA) ส่งคืน ATCA_BAD_PARAM; สถานะ = atcab_init(cfg); ถ้า (สถานะ == ATCA_SUCCESS) { ถ้า (ATCA_SUCCESS != (สถานะ = atcab_is_locked (โซน & ล็อค))) { ส่งคืน ATCA_FUNC_FAIL; } if (!lock) { ส่งคืน ATCA_NOT_LOCKED; } ส่งคืน ATCA_SUCCESS; } ส่งคืน ATCA_BAD_PARAM; } check_lock_zone(&cfg, LOCK_ZONE_CONFIG);

ขั้นตอนที่สี่: เขียนรหัส AES ในช่อง

ในส่วนนี้ คุณจะตั้งค่าคีย์ AES ส่วนตัวในช่องที่คุณกำหนดไว้ในการกำหนดค่าชิป

สำหรับตัวอย่างนี้ ผมจะใช้ช่องหมายเลข 9 ของชิป

คุณจำเป็นต้องรู้: คุณสมบัติพิเศษของชิปนี้คือ คุณสามารถเขียนข้อมูลลงในสล็อตได้เพียง 4 ไบต์หรือ 32 ไบต์เท่านั้น สำหรับ AES เราต้องการคีย์ 128 บิต ดังนั้นข้อมูล 16 ไบต์ ดังนั้นฉันจึงตัดสินใจเขียนลงในคีย์ขนาด 16 ไบต์ในแต่ละช่องเพื่อให้มีข้อมูล 32 ไบต์

ตอนนี้ฉันจะแสดงรหัสที่ใช้:

/** \brief เขียนคีย์ AES ในช่องที่กำหนด * \param[ใน] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] หมายเลขช่องคีย์คีย์ * \param[in] datakey key array uint8_t * \param[in] len ขนาดของอาร์เรย์คีย์ * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นรหัสข้อผิดพลาด */ ATCA_STATUS write_key_slot (ATCAIfaceCfg *cfg, คีย์ uint8_t, uint8_t *datakey, size_t len) { ถ้า (คีย์ 16) ส่งคืน ATCA_BAD_PARAM; ถ้า (len != 32) ส่งคืน ATCA_BAD_PARAM; สถานะ ATCA_STATUS = atcab_init(cfg); ถ้า (สถานะ == ATCA_SUCCESS) { สถานะ = atcab_write_zone (ATCA_ZONE_DATA, (uint16_t) คีย์ 0, 0, datakey, 32); ถ้า (status != ATCA_SUCCESS) ส่งคืนสถานะ; } สถานะการส่งคืน; }

สำหรับตัวอย่างนี้ ฉันจะใช้คีย์ AES สองคีย์ขนาด 16 ไบต์แต่ละรายการ:

// ตัวอย่างของ AES KEY (len 32)uint8_t example_of_key [32] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; write_key_slot(&cfg, 9, example_of_key, sizeof(example_of_key));

ถ้าการกระทำนี้ดีตอนนี้คุณต้องผ่านขั้นตอนสุดท้าย "ล็อคโซนข้อมูล"

ขั้นตอนสุดท้าย: ล็อค Data Zone

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

สำหรับการดำเนินการนี้ เราจะใช้ฟังก์ชันนี้:

/** \brief ตรวจสอบว่า DATA_ZONE หรือ CONFIG_ZONE ถูกล็อคหรือไม่

* \param[ใน] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] โซน LOCK_ZONE_DATA หรือ LOCK_ZONE_CONFIG * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นจะเป็นรหัสข้อผิดพลาด */ ATCA_STATUS check_lock_zone (ATCAIfaceCfg *cfg, uint8_t โซน) { สถานะ ATCA_STATUS; บูลล็อค = เท็จ; ถ้า (โซน != (uint8_t)LOCK_ZONE_CONFIG && โซน != (uint8_t)LOCK_ZONE_DATA) ส่งคืน ATCA_BAD_PARAM; สถานะ = atcab_init(cfg); ถ้า (สถานะ == ATCA_SUCCESS) { ถ้า (ATCA_SUCCESS != (สถานะ = atcab_is_locked (โซน & ล็อค))) { ส่งคืน ATCA_FUNC_FAIL; } if (!lock) { ส่งคืน ATCA_NOT_LOCKED; } ส่งคืน ATCA_SUCCESS; } ส่งคืน ATCA_BAD_PARAM; } check_lock_zone(&cfg, LOCK_ZONE_DATA);

หากการกระทำนี้ดี ชิปของคุณก็พร้อมใช้งาน

ขั้นตอนที่ 5: 3. การใช้ AES CBC Module

3. การใช้โมดูล AES CBC
3. การใช้โมดูล AES CBC

ฉันจะอธิบายวิธีเข้ารหัสและถอดรหัสข้อมูลด้วยอัลกอริทึม AES CBC และชิป Atecc608a

ข้อควรจำ: ก่อนใช้งานฟังก์ชันนี้ คุณต้องตั้งค่าชิปก่อน สำหรับสิ่งนี้ ให้ทำตามขั้นตอนที่ 2 ของบทความนี้

ชิปนี้มีโมดูล AES หลายประเภท (AES 128 บิต) เฉพาะ AES 128 บิตเท่านั้น:

  1. AES ปกติ
  2. AES CBC
  3. AES GCM (พร้อมแฮช GFM) (ดูวิกิพีเดียสำหรับคำอธิบายเพิ่มเติม)

เพื่อให้ใช้งานง่ายขึ้น ฉันได้สร้างสองฟังก์ชัน:

  1. aes_cbc_encrypt
  2. aes_cbc_decrypt

ฟังก์ชั่นทั้งสองนี้มีอยู่ใน Github ของฉัน

คำอธิบาย

ฉันเลือกใช้ AES CBC Algorithm เพราะมันปลอดภัยกว่า AES 128 บิตพื้นฐาน อัลกอริทึมนี้ใช้ Initial Vector เพื่อเข้ารหัสข้อมูลของคุณ

ข้อมูล

ด้านล่างฉันให้รายละเอียดแต่ละขั้นตอนของวิธีการเข้ารหัสและถอดรหัส แต่ฉันเขียนโค้ดสำหรับ Arduino ที่ใช้ฟังก์ชันทั้งสองนั้น คุณสามารถดูรหัสนี้ใน Github ของฉัน:

  • Github: Github ของฉัน
  • ตัวอย่างโค้ด "Encrypt/Decrypt": AES_crypto_example.ino

ขั้นตอนแรก: เข้ารหัสข้อมูลของคุณ

ในส่วนนี้ ผมจะแสดงวิธีการเข้ารหัสข้อมูลของคุณ

ขั้นแรกคุณจะต้องใช้ฟังก์ชันนี้:

/** \brief เข้ารหัสข้อมูลโดยใช้อัลกอริทึม AES CBC * \param[in] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] data Words to encypt (ต้องหารด้วย 16, ความยาวสูงสุด 240) * \param[in] len length ของ Words ที่จะเข้ารหัส (ต้องหารด้วย 16, ความยาวสูงสุด 240) * \param[out] iv Initial Vector ที่ใช้ใน AES CBC (ส่งคืนเวกเตอร์ใน var นี้) * \param[out] ciphertext ส่งคืนคีย์ข้อความ Cypher * \param[in] หมายเลขสล็อตของ key * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นจะเป็นรหัสข้อผิดพลาด */ ATCA_STATUS aes_cbc_encrypt (ATCAIfaceCfg *cfg, uint8_t *data, int len, uint8_t *iv, uint8_t * ciphertext, uint8_t คีย์) { atca_aes_cbc_ctx_t ctx; if (len > LIMIT_DATA_SIZE_CBC && len % 16 != 0) { Serial.print(F("ERROR: ATCA_BAD_PARAM")); ส่งคืน ATCA_BAD_PARAM; } uint8_t tmp_iv[IV_LENGTH_CBC]; uint8_t tmp_data[len]; สถานะ ATCA_STATUS = atcab_init(cfg); ถ้า (สถานะ == ATCA_SUCCESS) { สถานะ = atcab_aes_cbc_init (&ctx, คีย์, 0, tmp_iv); if (status != ATCA_SUCCESS) { Serial.print(F("ERROR Encrypt: atcab_aes_cbc_init, Code Error 0x")); Serial.println (สถานะ HEX); กลับ; } memcpy (iv, tmp_iv, IV_LENGTH_CBC); memcpy(tmp_data, ข้อมูล, เลน); int max = เลน / 16; สำหรับ (int j = 0; j <max; j++) { status = atcab_aes_cbc_encrypt_block (&ctx, &tmp_data[j * 16], &ciphertext [j * 16]); } if (status != ATCA_SUCCESS) { Serial.print(F("ERROR Encrypt: atcab_aes_cbc_encrypt_block, Code Error 0x")); Serial.println (สถานะ HEX); } สถานะการส่งคืน; } สถานะการส่งคืน; }

ฟังก์ชั่นนี้ใช้งานง่าย คุณต้องตั้งค่าสองสิ่ง:

  1. IV เปล่า (Initial Vector) ขนาด 16 Bytes
  2. ข้อมูลที่จะเข้ารหัส (ขนาดสูงสุด 240 ไบต์)

นี่คือตัวอย่าง "วิธีใช้ฟังก์ชันนี้"

ฉันต้องการเข้ารหัสคำว่า "AAAAAAAAAAAAA" โดยรหัสของฉันเขียนในช่องหมายเลข "9":

สถานะ ATCA_STATUS = atcab_init(&cfg); ถ้า (สถานะ != ATCA_SUCCESS) { Serial.println (F ("atcab_init () ล้มเหลว: รหัส -> 0x")); Serial.println (สถานะ HEX); } uint8_t ข้อความธรรมดา[16] = "AAAAAAAAAAAAA"; // ข้อความต้นฉบับ uint8_t iv[IV_LENGTH_CBC]; // Initial Vector uint8_t cypherdata [sizeof (ข้อความธรรมดา)]; // สถานะการเข้ารหัสข้อมูล = aes_cbc_encrypt (&cfg, ข้อความธรรมดา, sizeof (ข้อความธรรมดา), iv, cypherdata, 9);

หากการกระทำนั้นดี คุณจะมีข้อมูลที่เข้ารหัสในตัวแปร "cypherdata" และ Initial Vector ในตัวแปร "IV"

เก็บสองตัวแปรนั้นไว้เพื่อถอดรหัสข้อความของคุณ !

ขั้นตอนที่สอง: ถอดรหัสข้อมูลของคุณ

ในการถอดรหัสข้อมูลของคุณ คุณจะต้องมีสองสิ่ง:

  1. เวกเตอร์เริ่มต้น
  2. ข้อมูล Cypher (ข้อมูลที่เข้ารหัส)

ในการถอดรหัสข้อมูลของคุณ คุณจะต้องใช้ฟังก์ชันนี้:

/** \brief ถอดรหัสข้อมูลโดยใช้อัลกอริทึม AES CBC * \param[in] cfg การกำหนดค่าอินเทอร์เฟซแบบลอจิคัล การกำหนดค่า * ที่กำหนดไว้ล่วงหน้าบางอย่างสามารถพบได้ใน atca_cfgs.h * \param[in] ciphertext Words to decypt (ต้องหารด้วย 16, ความยาวสูงสุด 240) * \param[in] len length ของ Words ที่จะถอดรหัส (ต้องหารด้วย 16, ความยาวสูงสุด 240) * \param[in] iv Initial Vector เพื่อใช้ใน AES CBC * \param[out] plaintext ส่งคืนข้อความที่ถอดรหัสแล้วที่นี่ * \param[in] key หมายเลขสล็อตของคีย์ * \return ATCA_SUCCESS เมื่อสำเร็จ มิฉะนั้นจะเป็นรหัสข้อผิดพลาด */ ATCA_STATUS aes_cbc_decrypt (ATCAIfaceCfg *cfg, uint8_t *ciphertext, int len, uint8_t *iv, uint8_t * ข้อความธรรมดา, uint8_t คีย์) { atca_aes_cbc_ctx_t ctx; if (len > LIMIT_DATA_SIZE_CBC || len % 16 != 0) { Serial.print(F("ERROR Decrypt: ATCA_BAD_PARAM")); ส่งคืน ATCA_BAD_PARAM; } สถานะ ATCA_STATUS = atcab_init(cfg); ถ้า (สถานะ == ATCA_SUCCESS) { สถานะ = atcab_aes_cbc_init (&ctx, คีย์, 0, iv); ถ้า (สถานะ != ATCA_SUCCESS) { Serial.print (F ("ข้อผิดพลาดในการถอดรหัส: atcab_aes_cbc_init, รหัสผิดพลาด 0x")); Serial.println (สถานะ HEX); กลับ; } int max = len / 16; สำหรับ (int j = 0; j <max; j++) { status = atcab_aes_cbc_decrypt_block (&ctx, &ciphertext[j * 16], &plaintext[j * 16]); } if (status != ATCA_SUCCESS) { Serial.print(F("ERROR Decrypt: atcab_aes_cbc_encrypt_block, Code Error 0x")); Serial.println (สถานะ HEX); } สถานะการส่งคืน; } สถานะการส่งคืน; }

ฉันต้องการถอดรหัสข้อมูลก่อนหน้าของฉัน (ดูด้านล่าง ขั้นตอนแรก) สำหรับสิ่งนี้ฉันจะทำสิ่งนี้:

uint8_t ข้อความธรรมดา [16] = "AAAAAAAAAAAAA"; uint8_t iv[IV_LENGTH_CBC]; uint8_t cypherdata [ขนาด (ข้อความธรรมดา)]; uint8_t ถอดรหัสข้อมูล[ขนาด(ข้อความธรรมดา)]; สถานะ = aes_cbc_decrypt(&cfg, cypherdata, sizeof(cypherdata), iv, decryptdata, 9); ถ้า (สถานะ == ATCA_SUCCESS) { Serial.print ("ข้อความที่ถอดรหัสคือ: "); สำหรับ (size_t i = 0; i < sizeof (decryptdata); i++) { Serial.print((char)decryptdata); } Serial.println(""); } อื่น { // ดูไฟล์ atca_status.h สำหรับรหัส Error Serial.print(F("ไม่สามารถถอดรหัสได้ | รหัสข้อผิดพลาด 0x")); Serial.println (สถานะ HEX); กลับ; }

หากการกระทำนั้นดี คุณจะมีข้อมูลที่ถอดรหัสอยู่ในตัวแปร "decryptdata"

ตอนนี้คุณรู้วิธีใช้การเข้ารหัสและถอดรหัสด้วยชิป Atecc608a แล้ว

ขั้นตอนที่ 6: 5. ทำไมคุณถึงต้องใช้ชิปนี้

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

นี่คือตัวอย่างการใช้งานบางส่วน:

  1. ข้อมูลที่จัดเก็บไปยัง EEPROM ภายนอก: คุณสามารถรักษาความปลอดภัยข้อมูลของ EEPROM ภายนอกได้ และหากใครยังมี EEPROM นี้อยู่ เขาจะต้องใช้คีย์และ IV ในการถอดรหัส
  2. ส่งข้อมูลแบบไร้สาย: คุณสามารถส่งข้อมูลที่เข้ารหัสนี้โดยระบบไร้สาย (nrf24L01, RFM95W…) และหากมีใครขัดขวางข้อมูลของคุณ ข้อมูลนี้จะปลอดภัย
  3. รหัสผ่านที่เก็บไว้

คุณสามารถทำสิ่งต่างๆ ได้หลายอย่างด้วยชิปนี้ สามารถใช้ในหลายโครงการ ถ้ามีเวลาบอกหน่อยว่าจะใช้ชิปนี้ในโครงการอะไร ?

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

ขั้นตอนที่ 7: บทสรุป

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

ขอบคุณสำหรับการอ่านทุกอย่าง

สนุกกับมัน.

แนะนำ: