GPG (ย่อมาจาก GNU Privacy Guard)  เป็นเครื่องมือช่วยเข้ารหัสลับไฟล์หรือข้อความ ด้วยกุญแจสาธารณะ (public key)​ จนได้ไฟล์หรือข้อความที่อ่านไม่รู้เรื่อง จนกว่าจะได้ถอดรหัสลับด้วยกุญแจส่วนตัว (private key) จึงจะเป็นข้อความดั้งเดิม

กุญแจมีสองดอก คือ กุญแจสาธารณะที่จะให้ใครก็ได้ มีความสามารถเข้ารหัสลับได้อย่างเดียว กับกุญแจส่วนตัวที่มีแค่เจ้าของเท่านั้น ซึ่งสามารถถอดรหัสลับที่มาจากกุญแจสาธารณะที่เข้าคู่กัน นี่เรียกว่า asymmatric keys ฮะ

ข้อดี

เพราะความที่มันเป็น asymmatric key นี่แหละ เราจึงดูแลเฉพาะ private key ของเราเท่านั้น ส่วน public key จะแชร์ให้ใครกี่คนก็ได้ ทำให้เวลาแชร์ key ทำได้ง่ายขึ้น และไม่ต้องกลัวกุญแจหลุดไปสู่คนอื่นที่ไม่เกี่ยวข้องฮะ แถมขั้นตอนขึ้นระบบก็ใช้เวลาน้อยด้วย ใช้งานไม่ยากเลย

ขั้นตอนใช้งาน

ดู diagram ข้างล่างนี้นิดนึงฮะ

มีคนสองฝั่ง คือ ฝั่งผู้รับและผู้ส่ง ผู้รับจะเป็นคนถอดรหัสลับออกจากไฟล์ที่มาจากผู้ส่ง และผู้ส่งก็เป็นคนเข้ารหัสลับไฟล์

ผู้รับจะต้องมี private key และ public key โดยที่ public key ก็ส่งให้ฝั่งผู้ส่งเข้ารหัสลับมาให้ ส่วนรหัสผ่าน (passpharses) เป็นตัวเลือกเพิ่มเติมฮะ ไม่ได้บังคับว่าต้องมี แต่มีก็ดีเหมือนกัน เช่นเดียวกันกับ Checksum ที่เอาไว้ใช้ตรวจสอบไฟล์ว่าตรงกันกับต้นทาง

ของที่ต้องมีก่อน

GPG เราใช้แค่โปรแกรมของมันเท่านั้นฮะ ปกติแล้วจะ pre-install มาใน UNIX พร้อมอยู่แล้ว แต่ถ้าต้องติดตั้งเอง ก็ดูได้จากลิงก์นี้ https://gnupg.org/download/

ได้เวลาลงมือกันแล้ว

[ผู้รับ] เตรียมการก่อน

ผมสร้าง container ไว้สองตัว โดยให้ cent เป็นผู้รับ ส่วน cent2 เป็นผู้ส่งนะฮะ

[ผู้รับ] สร้างกุญแจของตัวเอง

ตอนนี้เราเป็น cent ก็คือผู้รับ ใช้คำสั่งนี้เพื่อเริ่มสร้างกุญแจกันฮะ

gpg --full-generate-key

โปรแกรมจะถามคำถามให้เราเลือกตอบ หรือกรอกข้อมูลไป ขอเน้นที่สองคำถามนี้ฮะ

  1. "Key is valid for?" ถามว่าเราจะสร้างกุญแจที่มีอายุเท่าไหร่ ตอบ 0 ถ้าให้กุญแจไม่มีวันหมดอายุ
  2. "Email address" จะเป็นค่าแทนกุญแจนี้เลยนะฮะ เวลาเข้าหรือถอดรหัสลับ ก็ใช้อีเมล เช็คให้ชัวร์ก่อนตอบนะฮะ

และแล้วกุญแจของ Adam ก็ถือกำเนิด

[ผู้รับ] Error: No pinentry

ถ้าเจอ Error ว่า gpg: problem with the agent: No pinentry แปลว่าเราต้องติดตั้ง pinentry ฮะ

yum install pinentry

yum ไม่ได้มีในทุก OS นะฮะ ลองเช็คของตัวเองก่อนว่าเป็น OS อะไร จะได้หาวิธีลง pinentry ถูกตัวฮะ

[ผู้รับ] ดูกุญแจที่มี

สร้างเสร็จแล้วก็เช็คสักนิดนึง ด้วยคำสั่งนี้

# list public keys
gpg --list-keys

# list private keys
gpg --list-secret-keys

[ผู้รับ] Export กุญแจสาธารณะของเรา

เรามีกุญแจแล้ว ขั้นตอนต่อไปคือเอากุญแจสาธารณะของเราไปให้ฝั่งผู้ส่งใช้งานฮะ เค้าจะต้องใช้กุญแจสาธารณะอันนี้ไปเข้ารหัสลับไฟล์ของเค้าส่งกลับมาให้เราอีกทีนึง

จากไดอะแกรมตอนแรก ตัวกลางคือ webserver นะฮะ แต่ผมชอบแชร์ไปเป็นไฟล์ให้ทางนั้น import เพราะสามารถควบคุมได้ว่าเราจะส่งให้ใครบ้าง แน่ใจได้ว่าเค้าจะได้รับกุญแจของเรา และ import ได้ปกติ

gpg --export -o <destination_path> -a

-o คือ output path บอกว่าเราจะ export ไว้ที่ไหน และ -a หมายถึง armor ascii output เป็นประเภทของไฟล์ฮะ

หน้าตาโปรแกรมตอน export จะเป็นประมาณนี้

[ผู้ส่ง] Import กุญแจ

เมื่อเรา export กุญแจสาธารณะไปแล้ว ตัดภาพไปที่ผู้ส่งบ้าง เขาต้อง import กุญแจด้วยคำสั่งนี้ฮะ

gpg --import <public_key_path>

ลองใช้คำสั่ง list key ถ้า import สำเร็จ เราจะได้กุญแจของ Adam มาฮะ

[ผู้ส่ง] กุญแจนี้ไว้ใจได้

import กุญแจมาใหม่ๆ ต้องกำหนดค่าให้โปรแกรมไว้ใจกุญแจตัวนี้ฮะ เพราะผู้รับคือ Adam เป็นบุคคลไว้ใจได้

gpg --edit-key <email_of_public_key>

ต่อจากนั้น ให้พิมพื trust ตามด้วย 5 เพื่อบอกว่า ไว้ใจในระดับสูงสุด (ultimately trust และ y เพื่อยืนยัน จบด้วย quit หลังเสร็จสิ้นกระบวนการฮะ

จบขั้นตอนนี้ ถือว่าเราได้กุญแจมาใช้งานได้แล้วล่ะฮะ

[ผู้ส่ง] สร้างไฟล์จริงขึ้นมา

ตอนนี้เราก็พร้อมที่จะส่งของจริงไปให้  Adam กันแล้วนะ เรามี sample_message.txt อยู่ในมือแล้วล่ะ

[ผู้ส่ง] Encrypt ไฟล์

ได้ไฟล์มาแล้ว ใช้คำสั่ง encrypt มันได้เลยฮะ

gpg --output <output_encrypted_file> --batch --yes -e -r <public_key_email> <original_file>

--batch --yes หมายถึง รันคำสั่งนี้ในรูปแบบ batch คือรันเป็น background

-e หมายถึง encryption

-r หมายถึง จะระบุอีเมลของผู้รับ หรือก็คือ recipient ฮะ

เอาล่ะ พร้อมส่งแล้วจ้า

[ผู้รับ] Decrypt ไฟล์

บัดนี้  Adam ได้รับไฟล์จากผู้ส่ง สมมติชื่อว่า Brian ก็ได้ฤกษ์เปิดจดหมายแล้วล่ะฮะ

gpg --output <destination_path> --batch --yes --decrypt <original_encrypted_file>

GPG จะพยายามเปิดไฟล์ที่เข้ารหัสลับนี้ ด้วยกุญแจส่วนตัวที่มีในเครื่องฮะ

เปิดไฟล์แล้วลองอ่านเนื้อในดูซิ

[ผู้ส่ง] ใส่รหัสผ่านก่อนเปิดไฟล์

เพิ่มความปลอดภัยเข้าไปอีกชั้น ด้วยการใส่รหัสผ่าน หรือ Passphrase

gpg --output <output_encrypted_file> --batch --yes -e -r <public_key_email> --passphrase <password> <original_file>

นัดแนะกับผู้รับด้วยนะฮะว่ารหัสผ่านคืออะไร

[ผู้รับ] Decrypt ไฟล์พร้อมรหัสผ่าน

ผู้ส่งบอกรหัสผ่าน ผู้รับอย่างเราก็แกะไฟล์ที่มีรหัสผ่าน ด้วยวิธีนี้ฮะ

gpg --output <destination_path> --batch --yes --passphrase <password> --decrypt <original_encrypted_file>

รหัสผ่านถูกต้อง ก็แกะไฟล์ได้แล้ว

[ผู้ส่ง] ส่ง checksum ไปอีก

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

GPG เองก็มีขั้นตอน sign checksum เพื่อให้ปลายทางแน่ใจได้ว่า เขาได้ไฟล์ที่ถูกต้อง และมาจากต้นทางที่ไว้ใจได้ฮะ

[ผู้ส่ง] Generate key ของผู้ส่งด้วย

การจะ sign checksum ได้เนี่ย ผู้ส่งต้องมีกุญแจของผู้ส่งเองด้วยนะ

รัน gpg --full-generate-key เหมือนเดิม และตอนนี้ Brian ก็มีกุญแจเป็นของตัวเองแล้ว

[ผู้ส่ง] Generate Checksum แล้ว sign

ไฟล์ Checksum สามารถสร้างได้ด้วยคำสั่งนี้

sha256sum <message_file> | awk '{print $1}' > <checksum_file>

ต้องบอกก่อนว่าคำสั่งsha256sum ใช้งานได้ใน CentOS ก่อนจะใช้คำสั่งนี้ก็เช็ค OS ของเครื่องก่อนนะฮะ ถ้าไม่ใช่ CentOS ก็ต้องหาคำสั่ง shasum ที่ใช้ได้ใน OS นั้นๆ

สมมติว่าได้ไฟล์ checksum มาแล้ว ก็ sign มันลงไปเลย

gpg --output <signed_checksum_file> --batch --yes --quiet --sign <checksum_file>

[ผู้รับ] ยืนยันไฟล์ Checksum แล้ว decrypt

Adam ได้ไฟล์ checksum มา ก็อยากรู้ว่าใครกันนะที่ส่งมา

gpg --verify <signed_checksum_file>

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

# calculate checksum on decrypted file
sha256sum <decrypted_file> | awk '{print $1}'

# decrypt the checksum from sender
gpg --output <checksum_file> --decrypt <sign_checksum_file>

อ้างอิง

GPG commands http://irtfweb.ifa.hawaii.edu/~lockhart/gpg/

Pinentry https://chaosfreakblog.wordpress.com/2013/06/21/gpg-problem-with-the-agent-no-pinentry-solved/