การจัดเก็บ Secret/Password สำหรับ Python Script ให้ปลอดภัย

Securely Managing Secrets/Passwords for Python Scripts

Nopnithi Khaokaew (Game)
2 min readMay 29, 2021

— — — — — — — — — — — — — — —
สารบัญเนื้อหาทั้งหมด (My Contents)
— — — — — — — — — — — — — — —

เชื่อว่ามือใหม่บางท่านอาจจะเคยนำ secret, key หรือ password ไป hard-coded ไว้ใน Python script โต้ง ๆ แบบนี้

username = 'nopnithi'
password = 'P@ssw0rd'

print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')

ซึ่งไม่สมควรอย่างยิ่ง เพราะมีโอกาสที่ secret, key หรือ password ของเราจะหลุดออกสู่สาธารณะได้ ลองมาดูวิธีที่ปลอดภัยกันดีกว่า…

วิธีที่ 1: ใช้ getpass()

วิธีนี้เป็นการให้ user ป้อน secret ด้วยตัวเองขณะรัน Python script ซึ่งการใช้ getpass() จะช่วยให้ขณะที่เราพิมพ์จะไม่แสดงข้อความขึ้นมาบน terminal

ตัวอย่างไฟล์ 1-getpass.py

from getpass import getpass

username = input('Enter username: ')
password = getpass('Enter password: ')
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')

รัน Python Script (1-getpass.py)

python3 1-getpass.py

จะได้

Enter username: nopnithi
Enter password:
-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd

ที่จริงวิธีการที่คล้ายกับการใช้ getpass() ยังมีอีกคือใช้ sys.argv ครับ แต่ผมไม่เขียนถึงเพราะส่วนตัวไม่ค่อยชอบเท่าไร ใครสนใจลอง Google หาดูตามคีย์เวิร์ดที่ให้ไปนะ

วิธีที่ 2: ใช้ Environment Variables

วิธีนี้เป็นการเก็บ secret เป็น variable environment ซึ่งทำให้โอกาสที่ secret จะหลุดออกไปในกรณีที่เราส่ง code ให้คนอื่นหรือเผลอ publish ขึ้น public ก็คงไม่มี

เพิ่ม Environment Variables

nano ~/.bashrc

หรือถ้าใช้ zshrc จะเป็น

nano ~/.zshrc

แล้วใส่ environment variable ด้านล่างนี้

export MYUSER=nopnithi
export MYPASS=P@ssw0rd

จากนั้นเซฟให้เรียบร้อยแล้วทำการรีโหลด shell setting ซะ

source ~/.bashrc

หรือ

source ~/.zshrc

ป.ล. ฝั่ง Windows ลองค้นหาวิธีใน Google ดูนะครับ

ตัวอย่างไฟล์ 2-environment-variables.py

import osusername = os.environ['MYUSER']
password = os.environ['MYPASS']
print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')

รัน Python Script

python3 2-environment-variables.py

จะได้

-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd

วิธีที่ 3: ใช้ GPG Encryption

วิธีนี้ปลอดภัยกว่าวิธีที่ 2 เพราะต่อให้มีใครใช้งานคอมพิวเตอร์ของเราก็ไม่สามารถเข้าถึง secret ได้อยู่ดี (encrypt ไว้)

ติดตั้ง GPG

pip3 install python-gnupg
brew install gpg

หรือถ้าท่านใช้ Ubuntu ก็เปลี่ยน brew install gpg เป็น apt install gpg

สร้างไฟล์ mysecret.txt

MYUSER=nopnithi
MYPASS=P@ssw0rd

Encrypt ไฟล์ mysecret.txt

gpg --symmetric -o encrypted.mysecret.gpg mysecret.txt

จากนั้นมันจะให้เรากำหนด passphrase (ผมกำหนดเป็น nopnithi)

เมื่อเสร็จเรียบร้อยแล้วเราจะได้ไฟล์ encrypted.mysecret.gpg ที่ถูก encrypt เอาไว้เรียบร้อย ก็ให้เราลบ mysecret.txt ทิ้งไปเลย (ไม่ได้ใช้แล้ว)

rm mysecret.txt

ลอง Decrypt ไฟล์ encrypted.mysecret.gpg

gpg --decrypt encrypted.mysecret.gpg

จะได้

gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
MYUSER=nopnithi
MYPASS=P@ssw0rd

ตัวอย่างไฟล์ 3-gpg-encryption.py

import osusername = os.getenv('MYUSER')
password = os.getenv('MYPASS')

print('-' * 20 + ' My Python Script ' + '-' * 20)
print(f'Username = {username}\nPassword = {password}')

รัน Python Script

env $(gpg --decrypt encrypted.mysecret.gpg) python3 3-gpg-encrytion.py

จะได้

gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
-------------------- My Python Script --------------------
Username = nopnithi
Password = P@ssw0rd

ระวัง! Flush Session ทิ้งด้วย

สังเกตว่าหลังจากที่เรากรอก passphrase ไป เราจะสามารถ decrypt ได้เรื่อย ๆ เพราะมันเก็บ session เอาไว้ ดังนั้นเราควร flush session ทิ้งด้วย

echo RELOADAGENT | gpg-connect-agent

ถ้าคิดว่าบทความนี้มีประโยชน์ ฝากกด clap, follow และ share บทความนี้ให้ผมด้วยนะครับ ขอบคุณมากครับ ^_^

--

--

Nopnithi Khaokaew (Game)
Nopnithi Khaokaew (Game)

Written by Nopnithi Khaokaew (Game)

Cloud Solutions Architect & Hobbyist Developer | 6x AWS Certified, CKA, CKAD, 2x HashiCorp Certified (Terraform, Vault), etc.