กลับไปหน้ารวมไฟล์
diy-advanced-iot-password-vault-synced-with-desktop-app-via-google-firebase-a7fca3.md

หลังจากทำ Midbar Firebase Edition V2.0 เสร็จ พี่ก็ตาสว่างว่าแม้มันจะเป็นตู้นิรภัยที่ใช้งานได้จริงและซิงค์กับแอปบนคอมได้ แต่มันยังไม่เวิร์คพออยู่ดี

เริ่มจากที่มันให้แค่เก็บข้อมูลล็อกอินได้อย่างเดียว แถมแอปบนคอมที่มากับเวอร์ชันนั้นก็ยังดิบๆ และช้าอีก เพราะมันต้องโหลดข้อมูลทั้งเรคคอร์ดจาก Google Firebase มาเลย ไม่ใช่แค่โหลดชื่อเรื่องมาโชว์ก่อน นั่นแปลว่าไม่มีฟังก์ชันพรีวิวให้ดูนั่นเอง

นอกจากนี้ ตัวฮาร์ดแวร์ตู้นิรภัยยังใช้หน้าจอจิ๋ว 160x128 และไม่สามารถจำลองตัวเองเป็นคีย์บอร์ด USB ได้อีกด้วย

เพื่อแก้จุดอ่อนพวกนี้ พี่เลยเอา Midbar V6.0 มาเป็นฐาน เปลี่ยนอัลกอริทึมการเข้ารหัส แล้วดัดแปลงให้ใช้ Google Firebase เป็นระบบไฟล์แทน พี่ยังทำแอปเดสก์ท็อปตัวใหม่ขึ้นมา ที่ให้ผู้ใช้ทำงานได้ไม่ใช่แค่ข้อมูลล็อกอิน แต่รวมถึงรายละเอียดบัตรเครดิต, โน้ต, และเบอร์โทรศัพท์ด้วย แอปเดสก์ท็อปในเวอร์ชันนี้จะโหลดข้อมูลทั้งเรคคอร์ดก็ต่อเมื่อกำลังดูหรือแก้ไขเท่านั้น ทำให้การสลับไปมาระหว่างสล็อตต่างๆ ในเมนูหลักเร็วขึ้นมาก

Midbar เวอร์ชันนี้เก็บข้อมูลที่เข้ารหัสไว้บนคลาวด์ ในขณะที่เก็บกุญแจการเข้ารหัสไว้บนตัวอุปกรณ์!

ถ้าน้องชอบความปลอดภัยแบบจัดเต็มมากกว่าความสะดวกสบาย — ลองไปดู [Midbar (Teensy 4.1) V3.0] ดูนะ หรือถ้าชอบแบบสะดวกสบายมากกว่า ก็ใช้แค่แอปเดสก์ท็อปโดยไม่มีฮาร์ดแวร์ตู้นิรภัยก็ได้ อีกทางเลือกคือใช้ [เวอร์ชันออฟไลน์ของแอปเดสก์ท็อป] ที่ไม่ซิงค์กับตู้นิรภัย

*หมายเหตุ: รูปภาพบางส่วนในบทสอนนี้เอามาจากบทสอนของ [Midbar V6.0] นะ เพราะนอกจากจะมีการปรับแต่งเล็กน้อยแล้ว GUI ของ Midbar ทั้งสองตัวนี้แทบจะเหมือนกันเลย

บทสอนนี้ยังมีให้อ่านบน [Instructables], [Medium], [Hackster], และ [Maker Pro] อีกด้วย

อัลกอริทึมการเข้ารหัส

Midbar Firebase Edition V3.0 ใช้อัลกอริทึมการเข้ารหัสตัวเดียวกันกับ Midbar Firebase Edition V2.0

Midbar จะรับข้อมูลจากผู้ใช้ แยกออกเป็นบล็อกขนาด 16 ไบต์ แล้วส่งแต่ละบล็อกไปเข้ารหัสด้วย AES-256

ข้อแตกต่างเพียงอย่างเดียวระหว่างการใช้งานโหมด cipher block chaining (CBC) ของ Midbar ทั้งสองเวอร์ชันกับการใช้งานโหมดนี้โดยทั่วไปก็คือ พี่เพิ่มการเพิ่มค่า key (key incrementation) เข้าไปด้วย เวลาอัลกอริทึมการเข้ารหัสรับข้อมูลเข้ามา มันจะสำรองคีย์ AES ไว้ แล้วเพิ่มค่าคีย์นั้นทุกครั้งหลังจากที่ AES ประมวลผลบล็อกหนึ่งเสร็จ พอประมวลผลข้อมูลทั้งหมดเสร็จ คีย์ AES ก็จะถูกคืนค่าไปสู่สถานะเริ่มต้น

จำไว้ว่าการเพิ่มค่าคีย์จะเริ่มจากไบต์ที่ 16 แล้วไล่ย้อนกลับมาที่ไบต์แรก

นี่คือฟังก์ชันเพิ่มค่าคีย์ที่เขียนด้วย Python

def incr_aes_key():                       
	  global aes_key                       
	  aes_key = bytearray(aes_key)                       
	  i = 15                       
	  while i >= 0:                       
	    if aes_key[i] == 255:                       
	      aes_key[i] = 0                       
	      i -= 1                       
	    else:                       
	      aes_key[i] += 1                       
	      break                       

การได้มาซึ่งคีย์ (Key Derivation)

Midbar Firebase Edition V3.0 เป็นเวอร์ชันแรกของ Midbar ที่ใช้ PBKDF2 ในการได้มาซึ่งคีย์การเข้ารหัส (cryptographic keys) จากรหัสผ่านหลัก (master password) ของผู้ใช้

PBKDF2 จะให้ผลลัพธ์ออกมา 96 ไบต์ ไบต์แรก 32 ไบต์ที่ได้จาก PBKDF2 จะถูกใช้เป็นคีย์ AES ไบต์ถัดไปอีก 32 ไบต์จะถูกใช้เป็นคีย์ HMAC และไบต์ที่เหลืออีก 32 ไบต์จะถูกเข้ารหัสและเก็บไว้ใน Google Firebase เพื่อตรวจสอบว่าผู้ใช้ป้อนรหัสผ่านหลักถูกต้องหรือไม่ตอนปลดล็อค Midbar

การตรวจสอบความสมบูรณ์ (Integrity Verification)

ฟีเจอร์ตรวจสอบความสมบูรณ์ของ Midbar นี้ทำงานบนพื้นฐานของ "HMAC-SHA256" เวลาน้องป้อนข้อมูลเข้าไปใน Midbar มันจะรวมข้อมูลทั้งหมดเป็นสตริงเดียว คำนวณแท็ก (tag) สำหรับสตริงนั้น แล้วบันทึกแท็กที่เพิ่งคำนวณมาใหม่ในรูปแบบที่เข้ารหัสไว้ พอน้องถอดรหัสข้อมูลของน้อง Midbar ก็จะถอดรหัสแท็กที่บันทึกไว้ก่อนหน้านี้ด้วย แล้วคำนวณแท็กใหม่สำหรับข้อมูลที่ถอดรหัสแล้ว จากนั้นมันก็จะเปรียบเทียบแท็กทั้งสองอัน ถ้ามันไม่ตรงกัน — Midbar จะแจ้งให้น้องรู้ว่าการตรวจสอบความสมบูรณ์ล้มเหลว งานเข้าแล้ววว!

ติดตั้งไดรเวอร์ CP210x และตั้งค่า Arduino IDE

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

ส่วนการตั้งค่า IDE นั้นไม่ได้อยู่ในบทสอนนี้แล้ว น้องต้องไปหาอ่านเพิ่มเติมเองเกี่ยวกับวิธีการติดตั้งบอร์ด ESP32 ใน Arduino IDE ให้เรียบร้อย

ดาวน์โหลดเฟิร์มแวร์

น้องสามารถดาวน์โหลดเฟิร์มแวร์สำหรับ Midbar ได้จาก repository ในส่วน "Code" ของโปรเจกต์ หรือไม่ก็ไปหาโหลดจากแหล่งอื่นๆ ที่มีให้ดาวน์โหลดเฟิร์มแวร์นี้

ดาวน์โหลดและติดตั้งไลบรารี่

ไลบรารี่ที่จำเป็นมีดังนี้: TFT_eSPI, PS2KeyAdvanced, PS2KeyMap, และ Firebase-ESP32 น้องต้องไปหาไลบรารี่เหล่านี้มาโหลดเองจากแหล่งที่เก็บไลบรารี่ทั่วไป (เช่น GitHub ของผู้พัฒนา) จัดไปวัยรุ่น!

วิธีการติดตั้งไลบรารี่ก็แบบปกติเลย น้องสามารถแตกไฟล์จากที่ดาวน์โหลดมาไว้ในโฟลเดอร์: …\Arduino\libraries หรือจะเปิด Arduino IDE ขึ้นมา แล้วคลิกที่ Sketch -> Include Library -> Add .ZIP Library… แล้วเลือกไฟล์ ZIP ของไลบรารี่แต่ละตัวก็ได้

ส่วนไลบรารี่อื่นๆ ที่จำเป็นที่เหลือ ก็มีอยู่ใน IDE อยู่แล้วในทางใดทางหนึ่ง สู้งานนะน้อง!

เปลี่ยนไฟล์ตั้งต้นของไลบรารี TFT_eSPI

ไลบรารี TFT_eSPI เนี่ย มันต้องปรับค่าคอนฟิกร่วมกันระหว่างจอ กับบอร์ดที่ใช้ขับจอตัวนั้น ตอนแรกพี่จะเขียนมินิไกด์สอนปรับคอนฟิกให้จอ ILI9341 ใช้งานกับ HSPI ของ ESP32 ถูกต้องเลย แต่คิดไปคิดมา มันง่ายกว่าถ้าแปะไฟล์คอนฟิกที่ปรับเสร็จแล้วในเฟิร์มแวร์ แล้วบอกน้องไปเลยว่าต้องเอาไปวางไว้ไหน

ให้น้องไปเอาไฟล์ "User_Setup.h" จากโฟลเดอร์ "Midbar-Firebase-Edition\V3.0" มา แล้วเอาไปวางไว้ในโฟลเดอร์ **C:\Program Files (x86)\Arduino\libraries\TFT_eSPI-master** จัดไปวัยรุ่น

ตั้งค่า Google Firebase

พี่ก็อยากจะสอนน้องตั้งค่า Firebase เองหรอกนะ แต่พี่ว่าในอินเตอร์เน็ตมีบทความดีๆ ที่อธิบายเรื่องนี้ได้ชัดเจนและเป็นขั้นตอนอยู่แล้ว พี่แนะนำให้น้องไปหาอ่านบทความเกี่ยวกับการเริ่มต้นใช้งาน ESP32 กับ Firebase ให้จบถึงหัวข้อ "Development Environment Setup" นะ

ตอนที่ตั้งค่าฐานข้อมูล (Database) อย่าลืมบันทึกค่า **Realtime Database URL** กับ **Web API Key** ไว้ให้ดีนะครับสองค่าเนี่ย

เราจะต้องใช้ค่าพวกนี้ในขั้นตอนต่อไป ห้ามลืมนะตัวนี้!

แก้ไขเฟิร์มแวร์

เปิดไฟล์ "Firmware_for_ESP32.ino" จากโฟลเดอร์ "...\V3.0\Firmware_for_ESP32" ขึ้นมา แล้วแก้ไขค่าของตัวแปรทั้งสี่ตัวนี้ให้ถูกต้อง:

WIFI_SSID

WIFI_PASSWORD

API_KEY

DATABASE_URL

แล้วก็ตรวจสอบค่าตามสองบรรทัดนี้ด้วย ถ้าจำเป็นก็ปรับให้เหมาะกับงานของน้อง:

#define MAX_NUM_OF_RECS 999

const unsigned int iterations = 20451;

เปลี่ยน Partition Scheme เป็น “Huge APP (3MB No OTA/1MB SPIFFS)”

ก่อนจะไปเล่นกับ ESP32 ต่อ น้องต้องเปลี่ยน Partition Scheme เป็น **Huge APP (3MB No OTA/1MB SPIFFS)** ก่อนนะ เพราะเฟิร์มแวร์ตัวนี้ตัวเบิ้มมาก โตเกินกว่าที่พาร์ทิชันตั้งต้นจะอัดลงไปได้ ห้ามช็อตนะตัวนี้!

อัพโหลดเฟิร์มแวร์ลง ESP32

อัพโหลดเฟิร์มแวร์ที่เราแก้ไขแล้วจากโฟลเดอร์ **…\V3.0\Firmware_for_ESP32** ลงไปใน ESP32 ของเราได้เลย สู้งานนะน้อง!

Flash STM32

ถ้าน้องอยากให้ Midbar จำลองตัวเป็นคีย์บอร์ด USB น้องต้องอัปโหลดเฟิร์มแวร์จากโฟลเดอร์ “…\V3.0\Firmware_for_STM32F103C8T6” ลงไปใน STM32F103C8T6 ให้ได้ก่อน

บอกเลยว่าการตั้งค่า Arduino IDE และการ Flash ลง STM32F103C8T6 นี่มันค่อนข้างจะซับซ้อนและใช้เวลาพอสมควรเลยนะ อย่าเพิ่งท้อน้า

มีบทความสอนดีๆ อยู่บทความนึงที่อธิบายวิธี Flash STM32F103C8T6 อย่างถูกต้อง (เป็นเวอร์ชันแปล Google Translate นะ) ลองไปอ่านดูได้

ประกอบอุปกรณ์

การประกอบอุปกรณ์นี่ไม่น่ายากเลย แค่ต่อคอมโพเนนต์ทั้งหมดที่ต้องใช้เข้ากับ ESP32 ให้ครบก็พอ แต่เรื่องขา “BL” ของจอ ILI9341 นี่ต้องระวังหน่อยนะ เพราะจอแต่ละรุ่น แต่ละเวอร์ชันมันต้องการไม่เหมือนกัน บางรุ่นบอกให้ต่อเข้ากับ +3.3V, บางรุ่นให้ต่อลงกราวด์ (GND), บางรุ่นก็ปล่อยไว้เฉยๆ ไม่ต้องต่ออะไรเลยก็ได้ ตรวจสอบสเปคของจอตัวเองดีๆ นะน้อง

รับ Firebase Private Key

ถ้าอยากให้แอปบนคอม (Desktop App) ของเราคุยกับ Firebase ได้ น้องต้องไปเอา Private Key มา แล้วเอาไปวางไว้ในโฟลเดอร์เดียวกับแอปฯ นั้น

วิธีทำตามนี้เลย จัดไปวัยรุ่น:

  1. เปิดฐานข้อมูล (Database) ของโปรเจคขึ้นมา;
  2. คลิกที่ไอคอนรูปฟันเฟือง “Settings”;
  3. คลิกที่แถบ “Project settings”;
  4. พอแท็บใหม่โหลดมาแล้ว ให้ไปที่แท็บ “Service accounts”;
  5. คลิกปุ่ม “Generate new private key”;
  6. ในป็อปอัปที่เด้งขึ้นมา ให้คลิกปุ่ม “Generate key”;
  7. เซฟ Private Key ไฟล์นั้นไว้ในโฟลเดอร์ “…\V3.0\Desktop App” โดยตั้งชื่อไฟล์ว่า firebase key.json ห้ามช็อตนะตัวนี้ ตั้งชื่อให้ถูกต้อง

ใส่ URL ของฐานข้อมูลลงในแอป Desktop

เข้าไปที่โฟลเดอร์ "…\V3.0\Desktop App" เปิดไฟล์ "db_url.txt" ขึ้นมา แล้วแทนที่ URL ฐานข้อมูลของพี่ด้วยของน้องเอง อย่าลืมกด "Ctrl + S" เพื่อเซฟ แล้วค่อยปิดไฟล์นะจ๊ะ

จ่ายไฟให้กับตู้เซฟ MCU