การรับส่งไฟล์แบบปลอดภัยด้วย PGP Encryption 🔒

Theeruttop (Toppy)

ระบบรับส่งไฟล์แบบปลอดภัยด้วย PGP

📖 บทนำ

การรักษาความลับและความสมบูรณ์ของข้อมูล (Data Confidentiality and Integrity) ในการแลกเปลี่ยน Interface File ระหว่างระบบภายในและภายนอกองค์กรเป็นสิ่งสำคัญสูงสุด โดยเฉพาะอย่างยิ่งสำหรับข้อมูลที่มีความอ่อนไหว เช่น ข้อมูลทางการเงินหรือข้อมูลส่วนบุคคล

PGP (Pretty Good Privacy) จึงถูกนำมาใช้เป็นมาตรฐานการเข้ารหัสแบบ Asymmetric Encryption ที่เชื่อถือได้ เพื่อรับประกันความปลอดภัยของข้อมูลในขณะส่งผ่านเครือข่าย

🔐 หลักการทำงานของ Asymmetric Encryption

พื้นฐานการเข้ารหัสแบบ Asymmetric

flowchart TD A[Public Key] -->|เข้ารหัส| B[Encrypted Data] B -->|ส่งผ่าน Network| C[Recipient] C -->|ถอดรหัสด้วย Private Key| D[Original Data] E[Private Key + Passphrase] -.->|จัดเก็บและใช้ใน Vault| C style A fill:#e0f2fe,stroke:#0277bd,stroke-width:2px style B fill:#fce4ec,stroke:#c2185b,stroke-width:2px style C fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style D fill:#e0f7fa,stroke:#00695c,stroke-width:2px style E fill:#ffebee,stroke:#d32f2f,stroke-width:2px

หลักการสำคัญ:

  • Public Key = ใช้สำหรับ เข้ารหัส ข้อมูล (Encryption), สามารถเผยแพร่ได้อย่างอิสระ
  • Private Key = ใช้สำหรับ ถอดรหัส ข้อมูล (Decryption), ต้องถูกเก็บเป็นความลับสูงสุดและไม่ส่งผ่านเครือข่าย
  • Passphrase = รหัสป้องกัน Private Key, ต้องจัดเก็บแยกจากตัว Private Key (Separation of Concern) เพื่อเพิ่มชั้นการป้องกัน (Defense-in-Depth)

🛠️ การใช้งานพื้นฐาน

1. การสร้าง Key Pair

# ===== การสร้าง Key Pair ด้วย GPG (Gnu Privacy Guard) =====
gpg --gen-key \                    # คำสั่งสร้าง key pair
    --pin-entry-mode loopback \    # ไม่ต้องการ GUI prompt
    --passphrase "your-secure-passphrase" \ # รหัสป้องกัน private key
    --batch \                      # ใช้ batch mode สำหรับ automation
    --yes                          # ตอบ yes อัตโนมัติ

# ===== การ Export Public Key (สำหรับส่งให้ Partner) =====
gpg --armor \                      # แปลงเป็น text format
    --export your@email.com \      # ระบุ Key ID (Email)
    > public_key.asc               # บันทึกเป็นไฟล์

# ===== การ Export Private Key (สำหรับจัดเก็บใน Vault) =====
gpg --armor \                      # แปลงเป็น text format
    --export-secret-key \          # export private key
    your@email.com \               # ระบุ Key ID (Email)
    > private_key.asc              # บันทึกเป็นไฟล์

2. การเข้ารหัสและถอดรหัส

# ===== การเข้ารหัสไฟล์ (ใช้ Public Key ของผู้รับ) =====
gpg --encrypt \
    --recipient "partner@email.com" \  # ระบุ Key ID ของผู้รับปลายทาง
    --armor \                          # สร้างไฟล์ Encrypted Output เป็น Text Format (.asc)
    --output encrypted_file.asc \      # ระบุชื่อไฟล์ Output
    input_file.txt                     # ไฟล์ที่ต้องการเข้ารหัส

# ===== การถอดรหัสไฟล์ (ใช้ Private Key ของตัวเอง) =====
gpg --decrypt \
    --output decrypted_file.txt \      # ระบุชื่อไฟล์ Output ที่ถอดรหัสแล้ว
    encrypted_file.asc                 # ไฟล์ Encrypted Input

🔄 สถานการณ์การใช้งานจริง

สถานการณ์ที่ 1: Partner ส่ง Interface File ให้เรา

flowchart TD A[เรา] -->|1 สร้าง Key Pair| B[Our Keys] B -->|2 ส่ง Public Key| C[Partner] C -->|3 Partner Import Key| D[Partner Ready] D -->|4 เข้ารหัสไฟล์ ใช้ Public Key ของเรา| E[Encrypted File] E -->|5 ส่งไฟล์ผ่าน Secure Channel| F[เรา] F -->|6 ถอดรหัส ใช้ Private Key ของเรา| G[Decrypted File] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style B fill:#fff3e0,stroke:#f57c00,stroke-width:2px style C fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style D fill:#e8f5e8,stroke:#388e3c,stroke-width:2px style E fill:#fce4ec,stroke:#c2185b,stroke-width:2px style F fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style G fill:#e0f7fa,stroke:#00695c,stroke-width:2px

ขั้นตอนการทำงาน:

  1. เราสร้าง Key Pair - สร้าง Public Key และ Private Key โดย Private Key และ Passphrase จะถูกจัดเก็บใน HashiCorp Vault
  2. ส่ง Public Key ให้ Partner - ส่ง Public Key ผ่านช่องทางที่ ปลอดภัย เช่น SFTP หรือ Secure Web Portal พร้อมแนบ Digital Signature และยืนยัน Fingerprint
  3. Partner Import และ Verify - Partner ตรวจสอบ Digital Signature และ Fingerprint ก่อน Import Public Key ของเราเข้าสู่ระบบ
  4. Partner เข้ารหัสไฟล์ - Partner ใช้ Public Key ของเรา ในการเข้ารหัส Interface File
  5. ส่งไฟล์ที่เข้ารหัส - ส่งไฟล์ที่เข้ารหัสแล้วมาให้เราผ่านช่องทางที่ ปลอดภัย
  6. เราถอดรหัส - Decryption Service ของเราดึง Private Key + Passphrase จาก Vault มาใช้ในการถอดรหัสไฟล์

ตัวอย่าง Command:

# ===== ฝั่งเรา (เตรียม Key สำหรับ Key Exchange) =====
# 1. Export public key (เพื่อส่งให้ Partner)
gpg --armor --export your@email.com > my_public_key.asc

# 2. (Best Practice) สร้าง Digital Signature เพื่อยืนยันตัวตน
gpg --detach-sign --armor my_public_key.asc

# 3. ส่ง my_public_key.asc และ my_public_key.asc.sig ผ่าน SFTP/Secure Portal

# ===== ฝั่ง Partner (รับและเข้ารหัส) =====
# 1. ตรวจสอบและ Import public key ของเรา
gpg --verify my_public_key.asc.sig my_public_key.asc # ตรวจสอบลายเซ็น
gpg --import my_public_key.asc

# 2. เข้ารหัสไฟล์ด้วย public key ของเรา
gpg --encrypt \
    --recipient "your@email.com" \
    --output encrypted_file.asc \
    input_file.txt

# ===== ฝั่งเรา (Decryption Service - โดย Microservice) =====
# (สมมติว่า Private Key และ Passphrase ถูกดึงจาก Vault มาใช้ใน Process แล้ว)
gpg --decrypt --output decrypted_file.txt encrypted_file.asc

สถานการณ์ที่ 2: เราส่ง Interface File ให้ Partner

flowchart TD A[Partner System] -->|1 สร้าง Key Pair| B[Partner Keys] B -->|2 ส่ง Public Key ผ่าน SFTP Secure Portal| C[เรา Encryption Service] C -->|3 เรา Import Verify Key| D[Our Keyring Ready] D -->|4 เข้ารหัสไฟล์ ใช้ Public Key ของ Partner| E[Encrypted File] E -->|5 ส่งไฟล์ผ่าน Secure Channel| F[Partner System] F -->|6 ถอดรหัส ใช้ Private Key ของ Partner| G[Decrypted File] style A fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style B fill:#fff3e0,stroke:#f57c00,stroke-width:2px style C fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style D fill:#e8f5e8,stroke:#388e3c,stroke-width:2px style E fill:#fce4ec,stroke:#c2185b,stroke-width:2px style F fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style G fill:#e0f7fa,stroke:#00695c,stroke-width:2px

ขั้นตอนการทำงาน:

  1. Partner สร้าง Key Pair - Partner สร้าง Public Key และ Private Key โดยจัดเก็บ Private Key และ Passphrase ไว้ในระบบของตนเองอย่าง ปลอดภัย
  2. ส่ง Public Key ให้เรา - Partner ส่ง Public Key ผ่านช่องทางที่ ปลอดภัย เช่น SFTP หรือ Secure Web Portal พร้อมแนบ Digital Signature
  3. เรา Import และ Verify - Encryption Service ของเราตรวจสอบ Digital Signature และ Fingerprint ก่อน Import Public Key ของ Partner เข้าสู่ระบบ
  4. เราเข้ารหัสไฟล์ - Encryption Service ของเราดึง Public Key ของ Partner มาใช้ในการเข้ารหัส Interface File
  5. ส่งไฟล์ที่เข้ารหัส - ส่งไฟล์ที่เข้ารหัสแล้วให้ Partner ผ่านช่องทางที่ ปลอดภัย (เช่น SFTP)
  6. Partner ถอดรหัส - Partner ใช้ Private Key + Passphrase ของตนเองในการถอดรหัสไฟล์

ตัวอย่าง Command:

# ===== ฝั่ง Partner (Key Exchange) =====
# 1. Export public key (พร้อม Digital Signature)
gpg --armor --export partner@email.com > partner_public_key.asc
gpg --detach-sign --armor partner_public_key.asc

# 2. ส่งไฟล์ public key และ signature ให้เราผ่าน Secure Channel

# ===== ฝั่งเรา (Encryption Service - รับ/Verify Key และเข้ารหัส) =====
# 1. ตรวจสอบและ Import public key ของ Partner
gpg --verify partner_public_key.asc.sig partner_public_key.asc # ตรวจสอบลายเซ็น
gpg --import partner_public_key.asc

# 2. เข้ารหัสไฟล์ด้วย public key ของ partner
gpg --encrypt \
    --recipient "partner@email.com" \
    --output encrypted_file.asc \
    input_file.txt

# 3. ส่งไฟล์ encrypted_file.asc ให้ Partner ผ่าน SFTP/Secure Portal

# ===== ฝั่ง Partner (ถอดรหัส) =====
# 1. ถอดรหัสไฟล์ด้วย private key + passphrase
gpg --decrypt --output decrypted_file.txt encrypted_file.asc
# ระบบจะถาม passphrase

🔑 การแลกเปลี่ยน Keys และ Secure Transfer

การแลกเปลี่ยน Public Key ต้องทำผ่านช่องทางที่มีความ ปลอดภัย (Secure Channel) และมีการตรวจสอบ Fingerprint เสมอ เพื่อป้องกันการโจมตีแบบ Man-in-the-Middle (MITM)

วิธีการส่งผ่าน Secure Channel (ช่องทางปฏิบัติจริง)

1. Secure File Transfer Protocol (SFTP) หรือ Secure Web Portal

นี่คือช่องทางหลักและเป็นมาตรฐานที่ใช้ในการแลกเปลี่ยน Interface File และ Keys ระหว่างองค์กร:

# ===== การส่ง Public Key ผ่าน SFTP/Secure Portal =====
# 1. Export Public Key
gpg --armor --export your@email.com > my_public_key.asc

# 2. (Best Practice) สร้าง Digital Signature เพื่อยืนยันความถูกต้อง
gpg --detach-sign --armor my_public_key.asc

# 3. ส่งไฟล์ Public Key (.asc) และ Signature (.asc.sig) ไปยัง SFTP Server ปลายทาง
sftp partner_user@secure-server.com
put my_public_key.asc /key_exchange/
put my_public_key.asc.sig /key_exchange/
quit

# ผู้รับจะดาวน์โหลดและใช้คำสั่ง gpg --verify เพื่อตรวจสอบลายเซ็น

2. Secure Email Transfer (ทางเลือกฉุกเฉิน)

หากจำเป็นต้องส่งผ่านอีเมล ควรแนบ Digital Signature และ Fingerprint เพื่อยืนยันตัวตน:

# ส่งไฟล์ Public Key (.asc) และไฟล์ Signature (.asc.sig)
# พร้อมทั้งส่ง Fingerprint ผ่านช่องทางที่ 3 ที่เชื่อถือได้ (เช่น โทรศัพท์ยืนยัน)
gpg --fingerprint your@email.com
# Output: ABCD 1234 EF56 7890 ABCD 1234 EF56 7890 ABCD 1234

🔑 การจัดเก็บ Keys ใน Vault (Best Practice)

การจัดการ Private Key ของระบบเราและ Public Key ของ Partner ต้องทำผ่าน HashiCorp Vault เพื่อให้ Microservice ดึง Key มาใช้ในการเข้ารหัส/ถอดรหัสได้โดยไม่ต้องเก็บ Key ไว้ในโค้ดหรือ File System ซึ่งเป็นหลักการ Secret Zero ที่สำคัญที่สุด

ตัวอย่าง Command สำหรับ Vault KV Secret Engine V2

คำสั่งผลลัพธ์ (ตัวอย่าง)คำอธิบาย
1. จัดเก็บ Private Key ของเรา
vault kv put secret/pgp/our-system/private-key key="-----BEGIN PGP PRIVATE KEY-----..."Key Value Secret written to: secret/data/pgp/our-system/private-keyจัดเก็บ Private Key ของระบบเรา ไว้ใน Vault Path ที่กำหนด
2. จัดเก็บ Passphrase ของเรา
vault kv put secret/pgp/our-system/passphrase passphrase="OurSecurePassphrase123!"Key Value Secret written to: secret/data/pgp/our-system/passphraseจัดเก็บ Passphrase แยกไว้คนละ Path เพื่อเพิ่มชั้นการป้องกัน (Defense-in-Depth)
3. จัดเก็บ Public Key ของ Partner
vault kv put secret/pgp/partners/system-a/public-key key="-----BEGIN PGP PUBLIC KEY-----..."Key Value Secret written to: secret/data/pgp/partners/system-a/public-keyจัดเก็บ Public Key ของ Partner ‘System A’ สำหรับการเข้ารหัส

หมายเหตุ: Microservice จะใช้ Vault Client ในการ Auth และดึง Key เหล่านี้มาใช้ในการทำงานแบบ Runtime ผ่าน Service Account ที่ถูกจำกัดสิทธิ์ (Least Privilege)


🛡️ การตรวจสอบความถูกต้องของ Keys (Verification)

การตรวจสอบนี้สำคัญที่สุดเพื่อยืนยันว่า Key ที่ได้รับมาเป็นของ Partner จริง ๆ และไม่มีการแก้ไขระหว่างการแลกเปลี่ยน

1. Fingerprint Verification

คือการตรวจสอบค่าแฮช (Hash) สั้นๆ ของ Public Key ผ่านช่องทางที่ เชื่อถือได้ (เช่น การโทรศัพท์ยืนยัน) เพื่อป้องกันการโจมตีแบบ Man-in-the-Middle (MITM)

# ===== คำสั่ง: ตรวจสอบ Fingerprint Key ที่ได้รับมา =====
gpg --fingerprint partner@email.com

# เปรียบเทียบกับ Fingerprint ที่ได้รับแจ้งจาก Partner (ต้องตรงกันทุกตัวอักษร)
ผลลัพธ์ตัวอย่างคำอธิบาย
pub rsa3072 2024-01-15 [SC]
Key fingerprint: **ABCD 1234 EF56 7890 ABCD 1234 EF56 7890 ABCD 1234**
Key Fingerprint 40 ตัวอักษรนี้จะต้องถูกเปรียบเทียบกับค่าที่ได้รับแจ้งจาก Partner ผ่านช่องทางที่ 3 (Out-of-Band) (ต้องตรงกันทุกตัวอักษร)

2. Digital Signature Verification

ใช้เพื่อตรวจสอบว่า Public Key File ที่ได้รับมาไม่ได้ถูกแก้ไขหรือ ปลอมแปลง ระหว่างทาง (Data Integrity) โดยใช้ลายเซ็นที่ Partner สร้างขึ้นจาก Private Key ของเขา

# ===== คำสั่ง: ตรวจสอบ Digital Signature ของ Public Key File =====
gpg --verify public_key.asc.sig public_key.asc
ผลลัพธ์ตัวอย่างคำอธิบาย
gpg: Signature made Tue 10 Jun 2025 10:00:00 AM ICT
gpg: **Good signature from "Partner System A <partner@email.com>"**
ระบบยืนยันว่าไฟล์ public_key.asc ถูกเซ็นโดย Private Key ที่สอดคล้องกับ Key ID ของ Partner (“Good signature…” คือสถานะที่ถูกต้อง)
gpg: BAD signature from "Partner System A <partner@email.com>"สถานะผิดพลาด: แสดงว่าไฟล์ Public Key อาจถูกแก้ไข, ลายเซ็นไม่ตรง, หรือถูกเซ็นด้วย Key ที่หมดอายุ (ห้าม Import)

3. Trust Level Setting

การตั้งค่าระดับความเชื่อถือ (Trust Level) ให้กับ Public Key ของ Partner ใน GPG Keyring

# ===== คำสั่ง: ตั้งค่า Trust Level (สำหรับ GPG Client) =====
gpg --edit-key partner@email.com # เข้าสู่โหมดแก้ไข Key
trust                             # พิมพ์คำสั่ง 'trust'
# เลือก trust level (เช่น 4 = full trust)
save                              # บันทึกและออกจากโหมดแก้ไข

Best Practices สำหรับ Key Exchange

1. Security Checklist (สิ่งที่ต้องปฏิบัติ)

สถานะรายการปฏิบัติคำอธิบาย
✅ใช้ Secure Channel เท่านั้นห้ามใช้ช่องทางที่ไม่เข้ารหัส (เช่น Email ธรรมดา) ในการส่ง Public Key
✅ตรวจสอบ Fingerprint ของ Public Keyยืนยันค่า Fingerprint ผ่านช่องทางที่สาม (Out-of-Band) เพื่อป้องกัน MITM
✅ใช้ Digital Signature เพื่อยืนยันความถูกต้องให้ Partner เซ็น Public Key ด้วย Private Key ของตนเอง เพื่อยืนยันตัวตน
✅ตั้ง Trust Level ที่เหมาะสมกำหนดระดับความเชื่อถือใน Keyring ของ GPG (เช่น Full Trust)
✅เก็บ Audit Log ของการแลกเปลี่ยน Keysบันทึกรายละเอียดการ Import/Export Key เพื่อการตรวจสอบย้อนหลัง
❌ไม่ส่ง Private Key ผ่าน NetworkPrivate Key ต้องถูกเก็บใน Vault และไม่เคยเผยแพร่สู่ภายนอก

2. Automation Script (ตัวอย่างการส่ง Key)

#!/bin/bash
# ===== Key Exchange Automation Script (ส่ง Public Key พร้อม Signature) =====

# ตรวจสอบ parameters
if [ $# -ne 2 ]; then
    echo "Usage: $0 <partner_email> <secure_server_user@host>"
    exit 1
fi

PARTNER_EMAIL=$1
SECURE_SERVER=$2

# 1. Export public key (เปลี่ยน your@email.com เป็น Key ID ที่ใช้จริง)
echo "1. Exporting public key..."
gpg --armor --export your@email.com > my_public_key.asc

# 2. สร้าง digital signature (ไฟล์ .asc.sig)
echo "2. Creating digital signature..."
gpg --detach-sign --armor my_public_key.asc

# 3. ส่งผ่าน SFTP (Secure File Transfer Protocol)
echo "3. Uploading to secure server..."
sftp $SECURE_SERVER << EOF
# อัปโหลด Public Key และ Signature ไปยังโฟลเดอร์สำหรับแลกเปลี่ยน Key
put my_public_key.asc /incoming/keys/
put my_public_key.asc.sig /incoming/keys/
quit
EOF

echo "Key exchange completed successfully!"
echo "Partner can download files from: $SECURE_SERVER/incoming/keys/"

🏗️ การใช้งาน PGP ใน Application Microservice (Spring Boot/Batch)

ในสถาปัตยกรรมที่เน้นความปลอดภัย Microservice (เช่น Spring Boot หรือ Spring Batch) จะทำหน้าที่เป็น Client ในการดึง PGP Keys (ที่จัดเก็บใน Vault) มาใช้ในการเข้ารหัส/ถอดรหัสไฟล์ ณ Runtime

ภาพรวมระบบ (Microservice + Vault Integration)

flowchart TD A[External System] -->|1 ส่ง-รับไฟล์| B[Our Microservice (Spring Boot/Batch)]; B -->|2 ดึง Keys Runtime| C[HashiCorp Vault]; B -->|3 ใช้ Keys ใน PGP Logic| D[PGP Processing Logic]; D -->|4 ส่งไฟล์กลับ| A; B -->|5 Audit Log| F[Monitoring]; style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px style C fill:#e8f5e8,stroke:#388e3c,stroke-width:2px style D fill:#fce4ec,stroke:#c2185b,stroke-width:2px style F fill:#fff3e0,stroke:#f57c00,stroke-width:2px

Microservice Responsibilities

Microservice จะถูกแบ่งบทบาทออกเป็น Components ที่ชัดเจน:

1. Application Encryption Component (Outbound File)

  • รับไฟล์ จาก Internal Application หรือ Spring Batch Reader
  • ดึง Public Key ของ External System จาก Vault ผ่าน Spring Cloud Vault Client
  • เข้ารหัสไฟล์ ด้วย Public Key ของ External System
  • ส่งไฟล์ที่เข้ารหัส กลับให้ External System
  • บันทึก Audit Log ทุกกิจกรรมการเข้ารหัส

2. Application Decryption Component (Inbound File)

  • รับไฟล์ที่เข้ารหัส จาก External System ผ่าน Spring Batch Job
  • ดึง Private Key + Passphrase จาก Vault
  • ถอดรหัสไฟล์ ด้วย Private Key + Passphrase ของเรา
  • ส่งไฟล์ที่ถอดรหัส ต่อไปให้ Internal Application เพื่อประมวลผล
  • บันทึก Audit Log ทุกกิจกรรมการถอดรหัส

3. Key Management Service (Maintenance)

  • จัดการ Public Keys ของ External Systems
  • จัดการ Private Key + Passphrase ของเรา
  • ตรวจสอบ Key Expiry และแจ้งเตือน (Monitor)
  • Rotate Keys ตามกำหนดเวลา

ตัวอย่างการใช้งานจริงใน Microservice (Java/Spring Boot)

สถานการณ์ที่ 1: External System ส่งไฟล์ให้เรา (Decryption)

// ===== PGP Decryption Service (Component ภายใน Application Service) =====
@Service
public class PGPDecryptionService {
    // ใช้ VaultClient ที่ Inject มาจาก Spring Cloud Vault
    private final VaultClient vaultClient;

    // ===== รับไฟล์ที่เข้ารหัสจาก External System =====
    @Async
    public void processIncomingEncryptedFile(String externalSystemId,
                                           String encryptedFilePath) {

        try {
            // 1. ดึง Private Key + Passphrase จาก Vault (Runtime Access)
            String privateKey = vaultClient.getSecret("pgp/private-key");
            String passphrase = vaultClient.getSecret("pgp/passphrase");

            // 2. ถอดรหัสไฟล์ด้วย Keys ที่ดึงมา
            String decryptedFilePath = decryptFile(encryptedFilePath,
                                                 privateKey,
                                                 passphrase);

            // 3. บันทึกไฟล์ที่ถอดรหัสแล้ว และบันทึก Audit Log
            fileStorage.storeDecryptedFile(decryptedFilePath);
            auditService.logFileDecryption(...);

        } catch (Exception e) {
            // จัดการ Error เช่น Keys ผิด หรือ Vault Access Error
            auditService.logDecryptionError(...);
        }
    }
}

สถานการณ์ที่ 2: เราส่งไฟล์ให้ External System (Encryption)

// ===== PGP Encryption Service (Component ภายใน Application Service) =====
@Service
public class PGPEncryptionService {

    private final VaultClient vaultClient;
    private final ExternalSystemClient externalSystemClient;
    private final AuditService auditService;

    // ===== ส่งไฟล์ที่เข้ารหัสให้ External System =====
    @Async
    public void sendEncryptedFileToExternalSystem(String externalSystemId,
                                                String filePath) {

        try {
            // 1. ดึง Public Key ของ External System จาก Vault
            String publicKey = vaultClient.getSecret(
                "external-systems/" + externalSystemId + "/public-key");

            // 2. เข้ารหัสไฟล์
            String encryptedFilePath = encryptFile(filePath, publicKey);

            // 3. ส่งไฟล์ที่เข้ารหัสให้ External System
            externalSystemClient.uploadFile(externalSystemId, encryptedFilePath);

            // 4. บันทึก Audit Log
            auditService.logFileEncryption(externalSystemId,
                                         filePath,
                                         encryptedFilePath);

        } catch (Exception e) {
            // จัดการ error
            auditService.logEncryptionError(externalSystemId,
                                          filePath,
                                          e.getMessage());
        }
    }
}

การจัดการ Keys ใน Vault

การจัดเก็บ PGP Keys ทั้งหมดต้องทำผ่าน HashiCorp Vault เพื่อให้ Microservice สามารถดึง Key มาใช้ในการทำงานได้ ณ Runtime โดยไม่ต้องมีการ Hardcode หรือจัดเก็บใน File System

# ===== การจัดเก็บ Keys ใน Vault KV Secret Engine V2 =====

# 1. Private Key และ Passphrase ของเรา (สำหรับ Decryption)
vault kv put secret/pgp/private-key key="-----BEGIN PGP PRIVATE KEY-----..."
vault kv put secret/pgp/passphrase passphrase="OurSecurePassphrase123!"

# 2. Public Keys ของ External Systems (สำหรับ Encryption)
vault kv put secret/external-systems/system-a/public-key \
    key="-----BEGIN PGP PUBLIC KEY-----..."
vault kv put secret/external-systems/system-b/public-key \
    key="-----BEGIN PGP PUBLIC KEY-----..."

# 3. การเข้าถึง Keys (Least Privilege):
# Microservice จะใช้ Service Account Token (ผ่าน Kubernetes Auth Method)
# เพื่อ Authenticate กับ Vault และดึง keys ที่จำเป็นสำหรับการเข้ารหัส/ถอดรหัสเท่านั้น

การ Monitor และ Alert

Service ต้องมีการตรวจสอบ (Monitor) สถานะของ Keys และบันทึกกิจกรรมต่างๆ เพื่อรักษาความปลอดภัย และเตรียมพร้อมสำหรับการหมุนเวียน Keys (Rotation)

// ===== Key Monitoring Service (Java/Spring Boot @Scheduled) =====
@Service
public class KeyMonitoringService {

    @Scheduled(fixedRate = 86400000) // ตรวจสอบทุก 24 ชั่วโมง (86.4 ล้าน ms)
    public void checkKeyExpiry() {

        // ตรวจสอบ keys ที่จะหมดอายุใน 30 วันล่วงหน้า
        List<KeyInfo> expiringKeys = vaultClient.getExpiringKeys(30);

        for (KeyInfo key : expiringKeys) {
            // ส่ง alert ไปยัง Security Team หรือ Operation Team
            alertService.sendKeyExpiryAlert(key);
        }
    }

    @EventListener
    public void handleEncryptionError(EncryptionErrorEvent event) {
        // แจ้งเตือนเมื่อเกิด error ในการเข้ารหัส (เช่น Public Key ของ Partner ผิดพลาด)
        alertService.sendEncryptionErrorAlert(event);
    }

    @EventListener
    public void handleDecryptionError(DecryptionErrorEvent event) {
        // แจ้งเตือนเมื่อเกิด error ในการถอดรหัส (เช่น ไฟล์เสียหาย หรือ Private Key ผิด)
        alertService.sendDecryptionErrorAlert(event);
    }
}

Best Practices สำหรับ Microservice

1. Security 🔒

  • ใช้ Vault สำหรับจัดการ Keys และ Secrets ทั้งหมด (Secret Zero Principle)
  • แยก Private Key และ Passphrase ในการจัดเก็บ (Defense-in-Depth)
  • ใช้ Service Account ที่จำกัดสิทธิ์ (Least Privilege) สำหรับการเข้าถึง Vault
  • เข้ารหัสข้อมูล ในทุกสถานะ (in transit และ at rest)

2. Monitoring 📊

  • Audit Log ทุกการเข้ารหัส/ถอดรหัส (เพื่อการตรวจสอบย้อนหลัง)
  • Monitor Key Expiry และแจ้งเตือนล่วงหน้า (เพื่อวางแผน Key Rotation)
  • Track Error Rates และ performance metrics ของ PGP Component
  • Alert on Security Events เช่น failed decryption attempts

3. Scalability 🚀

  • Async Processing สำหรับการเข้ารหัส/ถอดรหัสไฟล์ (ไม่บล็อก Main Thread)
  • Queue-based Processing สำหรับไฟล์ขนาดใหญ่และปริมาณงานสูง
  • Horizontal Scaling ของ Microservice ที่รัน PGP Logic
  • Caching สำหรับ frequently used keys (ลด Latency ในการเรียก Vault)

4. Error Handling 🚧

  • Retry Logic สำหรับ transient failures (ความล้มเหลวชั่วคราว)
  • Circuit Breaker สำหรับ external system calls (ป้องกันการเรียกซ้ำระบบภายนอกที่ไม่ตอบสนอง)
  • Dead Letter Queue (DLQ) สำหรับไฟล์ที่ไม่สามารถประมวลผลได้ (ตรวจสอบสาเหตุภายหลัง)
  • Graceful Degradation เมื่อ Vault ไม่สามารถเข้าถึงได้ (เช่น การใช้ Local Cache ชั่วคราว ภายใต้เงื่อนไขที่ปลอดภัย)

📋 สรุป

การใช้งาน PGP Encryption สำหรับการรับส่งไฟล์แบบปลอดภัยในสถาปัตยกรรม Microservice มุ่งเน้นไปที่การผสานรวม HashiCorp Vault โดยมีขั้นตอนหลักดังนี้:

  1. การสร้าง Key Pair - สร้าง public key และ private key พร้อม passphrase
  2. การแลกเปลี่ยน Public Keys - ผ่าน secure channel พร้อมการตรวจสอบความถูกต้อง (Verification)
  3. การเข้ารหัสไฟล์ - ใช้ public key ของผู้รับ
  4. การส่งไฟล์ - ควรส่งผ่านช่องทางที่ ปลอดภัย (แม้ไฟล์จะเข้ารหัสแล้วก็ตาม)
  5. การถอดรหัส - ใช้ private key + passphrase ของผู้รับ (ที่ดึงมาจาก Vault)

ในระบบ Microservice การจัดการ keys จะทำผ่าน Vault เพื่อความปลอดภัย และมีการ Monitor ตลอดเวลาเพื่อให้แน่ใจว่าระบบทำงานได้อย่างต่อเนื่องและปลอดภัย