Ghi chú về GPG
Giới thiệu
GnuPG là chương trình máy tính được lập trình theo chuẩn OpenGPG định nghĩa tại RFC4880. GnuGPG phép mã hóa dữ liệu hay thực hiện ký điện tử. Trên Ubuntu Linux, bạn có thể cài gpg bằng câu lệnh sudo apt install gpg
. GnuPG được dùng ở rất nhiều nơi trong hệ điều hành Ubuntu:
- Ký gói phần mềm (deb package): các gói deb sẽ được ký bởi Ubuntu Developer trước khi phát hành lên repository.
gpg
được dùng để quản lý khóa công khai choapt
.
GnuPG cung cấp các chức năng cho phép:
- Mã hóa / Giải mã dữ liệu sử dụng các thuật toán mã hóa phổ biến.
- Quản lý chìa khóa.
- Ký điện tử dữ liệu.
Khái quát mã công khai
Mã công khai bao gồm 2 chìa khóa: khóa bí mật và khóa công khai. Thuật toán mã công khai bí mật bảo đảm rằng rất khó để có thể biết được khóa bí mật từ khóa công khai trong khi đó không khó để biết khóa công khai từ khóa bí mật. Khóa công khai sẽ được thông báo với tất cả các bên tham gia truyền thông trong khi khóa bí mật chỉ được người sở hữu biết.
Cả khóa công khai và khóa bí mật đều có thể dùng để mã hóa dữ liệu.
- Khóa công khai được dùng để mã hóa dữ liệu: chỉ người có khóa bí mật có thể giải mã. Trường hợp này có thể được sử dụng nếu muốn gửi một bức thư mà chỉ người có khóa bí mật có thể đọc.
- Khóa bí mật để mã hóa dữ liệu: tất cả mọi người có khóa công khai đều có thể giải mã dữ liệu. Trường hợp này dùng trong chữ ký điện tử. Khi một bức thư được gửi đi với chữ ký (là dữ liệu được mã hóa bởi khóa bí mật), tất cả người nhận dùng khoá công khai có thể khẳng định bức thư thực sự đến từ người gửi (vì chỉ có người gửi có khóa bí mật).
Một số tính năng thông dụng của gpg
Nếu chương trình gpg
chưa được cài đặt, dùng câu lệnh sudo apt install gpg
để cài đặt. Nếu gpg
chạy lần đầu tiên, kho khóa của user chạy câu lệnh sẽ được tạo tại ${HOME}/.gnupg/pubring.kbx
.
Mặc định các câu lệnh gpg sẽ xuất ra dữ liệu binary. Để gpg
xuất ra dữ liệu ascii, lựa chọn --armor
cần được chỉ định khi chạy chương trình.
1) Tạo khóa
Trước khi bắt đầu mã hóa/giải mã/hay ký dữ liệu, một cặp khóa cần được tạo hay import vào kho khóa của gpg.
Tạo khóa. Chọn thuật toán RSA 4096 bits với thời hạn 1 năm, Realname là “GnuPG Testkey”. Sau khi nhập các dữ liệu trên, khóa sẽ được tạo với kết quả như dưới đây.
# gpg --full-generate-key
...
gpg: /home/ubuntu/.gnupg/trustdb.gpg: trustdb created
gpg: key AC9F02A2880FC94D marked as ultimately trusted
gpg: directory '/home/ubuntu/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/ubuntu/.gnupg/openpgp-revocs.d/A32AF7386251D58AF96CD7C5AC9F02A2880FC94D.rev'
public and secret key created and signed.
pub rsa4096 2024-06-25 [SC] [expires: 2025-06-25]
A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
uid GnuPG Testkey (Demo GnuPG) <testkey@local>
sub rsa4096 2024-06-25 [E] [expires: 2025-06-25]
2) Liệt kê khóa
Liệt kê khóa lưu trữ ở kho khóa bằng --list-keys
hoặc chỉ định khóa công khai hay bí mật.
# gpg --list-keys
# gpg --list-public-keys
# gpg --list-secret-keys
Với khóa được tạo ở trên, --list-keys
cho kết quả như dưới đây:
# gpg --list-keys
/home/ubuntu/.gnupg/pubring.kbx
-------------------------------
pub rsa4096 2024-06-25 [SC] [expires: 2025-06-25]
A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
uid [ultimate] GnuPG Testkey (Demo GnuPG) <testkey@local>
sub rsa4096 2024-06-25 [E] [expires: 2025-06-25]
ID Khóa có thể được tham khảo bằng 8 ký tự cuối của chuỗi ID 880FC94D
.
3) Export/Import khóa
Export
# gpg --export 880FC94D
# gpg --export -a 880FC94D
Import Khóa có thể được import từ file hay từ keyserver (là nơi để mọi người chia sẽ khóa).
# gpg --import /etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
gpg: key 871920D1991BC93C: 1 signature not checked due to a missing key
gpg: key 871920D1991BC93C: public key "Ubuntu Archive Automatic Signing Key (2018) <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2025-06-25
# gpg --list-keys
/home/ubuntu/.gnupg/pubring.kbx
-------------------------------
pub rsa4096 2024-06-25 [SC] [expires: 2025-06-25]
A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
uid [ultimate] GnuPG Testkey (Demo GnuPG) <testkey@local>
sub rsa4096 2024-06-25 [E] [expires: 2025-06-25]
pub rsa4096 2018-09-17 [SC]
F6ECB3762474EDA9D21B7022871920D1991BC93C
uid [ unknown] Ubuntu Archive Automatic Signing Key (2018) <[email protected]>
Tìm kiếm và import từ keyserver.
# gpg --keyserver keyserver.ubuntu.com --search-keys 0547d020
gpg: data source: http://[2620:2d:4000:1007::70c]:11371
(1) Bui Hong Ha (Work email) <[email protected]>
Bui Hong Ha <[email protected]>
3072 bit RSA key 0C1E5DC50547D020, created: 2019-02-19
Keys 1-1 of 1 for "0547d020". Enter number(s), N)ext, or Q)uit > Q
gpg: error searching keyserver: Operation cancelled
gpg: keyserver search failed: Operation cancelled
# gpg --keyserver keyserver.ubuntu.com --recv-keys 0547d020
gpg: key 0C1E5DC50547D020: public key "Bui Hong Ha (Work email) <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1
Một số keyserver phổ biến:
4) Mã hóa/giải mã dữ liệu
Chuẩn bị dữ liệu.
# echo "Important messages" > data.txt
# cat data.txt
Important messages
Mã hóa. File kết quả data.txt.gpg
có thể được dùng để gửi cho người nhận. gpg
sẽ mã hóa file data.txt
sử dụng khóa công khai của user testkey@local
.
# gpg --encrypt --recipient testkey@local data.txt
# ls
data.txt data.txt.gpg
# file data.txt.gpg
data.txt.gpg: PGP RSA encrypted session key - keyid: BD766384 26A0D34D RSA (Encrypt or Sign) 4096b .
Nếu bạn muốn file mã hóa có định dạng text ascii thay vì dữ liệu, dùng lựa chọn --armor
.
# gpg --encrypt --armor --recipient testkey@local data.txt
# ls
data.txt data.txt.asc data.txt.gpg
# cat data.txt.asc
-----BEGIN PGP MESSAGE-----
hQIMA712Y4QmoNNNAQ/9FcJw17cRFzYytBMWkV+7ub2b88a/bUnqYm49xNsU36Sx
mHGnDUW9RwNoM7JzHzXljp/n2nBDv15xBVvWdujouhzKRKO3ieOr5fFF03VDT//h
8x38me0h6lTD1ENd5zgVEFX5h94uAp5gP5xZ7MPYh5Idpd5iGfY07YDXlEyEG325
inpBitcEUatfee6yqn00jot8ADfeqlQLC1hlOFOQrBmokxAHE6oemICwJByIDEsJ
Q9/IOFblIBAuqV3jrVb9nYpzdOTiWd6P6qJmUKFHpefjVm6ZLUlHcM2U3ck+GKRQ
1D1XwVrudIhrz1pYLTfFQFZMKhXPS2j93X+H7zxUn3oM1WaBGpYH+ZlyDq/XUkC6
lwz+K70LLHxrWGNKe3i1dJcvdLnTFNrwBmtdGDDFyVHyW7zCQVmLUwOV3SD9Hy9W
UnUXQGNf2iQU1+TYSCD9ZYiVaepEhvHIezWOy23nvO16+KVtrYgpGkpZta6Amm3J
PWp3CCzSKBJJVcib2EZAKkKm1oVL84fnmwpxZ81w3R9ZGDoQuzQAORjlCSOgTFX8
esU1/FVoiIttVZDO+HL5PKVuKue/2V5AA065sp7Vcgnmo8UuWcqVwNUWqtrJa+7Y
wu5+U2iWBEeTcLyIUvOlEdj0/dAvKpOpg/KKBTZRo0eQTJ1a9C1cQ2CjKG8x7DvS
VgEcN0ggDyhqOPWI7EDzke+UgGwT/Brhx6Mjq5Uw+yMmp/In8KzQcsgUg3f1CuLE
+RQKi91MB3xH0B+xUa4cRdHuJMSG/cgl8P3/kbdr048t2gAjPHj2
=Tn05
-----END PGP MESSAGE-----
Giải mã dùng lựa chọn --decrypt
. Nếu khóa bí mật của bạn có passphrase, bạn phải nhập passphrase để có thể mở khóa bí mật.
# gpg --decrypt data.txt.gpg
gpg: encrypted with 4096-bit RSA key, ID BD76638426A0D34D, created 2024-06-25
"GnuPG Testkey (Demo GnuPG) <testkey@local>"
Important messages
#
# gpg --decrypt data.txt.asc
gpg: encrypted with 4096-bit RSA key, ID BD76638426A0D34D, created 2024-06-25
"GnuPG Testkey (Demo GnuPG) <testkey@local>"
Important messages
5) Ký điện tử
Giả định thay vì bạn muốn gửi data.txt
cho user testkey@local
, bạn là user testkey@local
muốn gửi data.txt
cho tất cả mọi người trong khi muốn chứng minh người gửi chính là bạn. Trong trường hợp này, bạn cần gửi kèm data.txt
kèm chữ ký điện tử. gpg
cho phép bạn làm điều này.
# gpg --sign data.txt
# ls
data.txt data.txt.gpg
# file data.txt.gpg
data.txt.gpg: data
# gpg --sign -a data.txt
# ls
data.txt data.txt.asc data.txt.gpg
# cat data.txt.asc
-----BEGIN PGP MESSAGE-----
owEBaAKX/ZANAwAKAayfAqKID8lNAawhYghkYXRhLnR4dGZ62IxJbXBvcnRhbnQg
bWVzc2FnZXMKiQIzBAABCgAdFiEEoyr3OGJR1Yr5bNfFrJ8CoogPyU0FAmZ62IwA
CgkQrJ8CoogPyU3ZmxAAjhDERfKRrlP5OxlqoAdaqsvtWP7A5p9jDbV5xCcrMjZW
kY5C7D3GNBhVpXjL3qnBRcjgDHEo3xcjMh84iiFKKlSUxpBQBfFvDEuJmHhPvVAr
k8aKpnqXecJ2zSGfiw6dAqw4TZVGmEoQd5ThBR/4eAKpBk+X4zDnIluDMkKHfT8e
DZFkU2FcYHNUFewUHgaA37svgOLf4lL+A7bONxFTNlawrVkbefcIIjYppwkVgioa
rbULDTCjLeKdO/x/dgh521G/wamobZlOaRta5UjYmSPR5uOYI9AHOm14UTkFE6uu
ZlkpIJhgjMndIdDi50qD9jRtAtyIf32HJW/ec/iSGK1/M1T0HDQPE7Z7DfShd0Pe
Ovg8Fkj7IHR8QLu9l7uN9+AX9RcZw9MQuzbbCmaI+7ihRvhBrm6Apw4gFyRRcy/5
eNJQJqVe61VqPf8akKRXthxv/BH4+ioHuzbetCNB9KsFt8fhMf9m6wiPTf2HHUaZ
GjvHEBOJk8uVGq5bFJ82NmLyL2vkFl/a7QShy734LnPPvQBDmOpkEJaMRiD/G18x
BLHtuLcUQUpZyItuLbCCDIlbU4COFHZNQRHvUpbm+8ulfGReOih2gSsxidMKB6V5
hBKkGWbt3v4RfkJLptse6jCFDI+PJXDRLBbo8ONbU3GiBGBc8nHdIcxjBNh48Mw=
=hb3d
-----END PGP MESSAGE-----
6) Kiểm tra chữ ký điện tử
# gpg --list-packets data.txt.gpg
# off=0 ctb=a3 tag=8 hlen=1 plen=0 indeterminate
:compressed packet: algo=1
# off=2 ctb=90 tag=4 hlen=2 plen=13
:onepass_sig packet: keyid AC9F02A2880FC94D
version 3, sigclass 0x00, digest 10, pubkey 1, last=1
# off=17 ctb=ac tag=11 hlen=2 plen=33
:literal data packet:
mode b (62), created 1719326733, name="data.txt",
raw data: 19 bytes
# off=52 ctb=89 tag=2 hlen=3 plen=563
:signature packet: algo 1, keyid AC9F02A2880FC94D
version 4, created 1719326733, md5len 0, sigclass 0x00
digest algo 10, begin of digest 01 e3
hashed subpkt 33 len 21 (issuer fpr v4 A32AF7386251D58AF96CD7C5AC9F02A2880FC94D)
hashed subpkt 2 len 4 (sig created 2024-06-25)
subpkt 16 len 8 (issuer key ID AC9F02A2880FC94D)
data: [4094 bits]
# gpg --verify data.txt.gpg
gpg: Signature made Tue Jun 25 14:45:33 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
Kết quả “Good signature” cho thấy chữ ký này quả thực đến từ user testkey@local
. Muốn đọc nội dung kèm trong chữ ký điện tử này, dùng gpg --decrypt
.
# gpg --decrypt data.txt.asc
Important messages
gpg: Signature made Tue Jun 25 14:47:40 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
7) Ký chứng thực nhưng không mã hóa
gpg
cho phép ký chứng thực mà không cần mã hóa. Người nhận có thể đọc nội dung trực tiếp trong khi vẫn có thể kiểm tra tính xác thưc của nội dung.
# gpg --clear-sign data.txt
File 'data.txt.asc' exists. Overwrite? (y/N) y
# cat data.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Important messages
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEoyr3OGJR1Yr5bNfFrJ8CoogPyU0FAmZ62kMACgkQrJ8CoogP
yU0THRAA0Ph/NiHuOiBb9qyiN0doBXoE8mTCKyBHPMWAK4J0aro48x9022icnmDy
+GGvulbg+bCQlxPzACa1MYux7dA1b/XqFOQ1yh3FQPqlY+JhygYsHAvUnd9yamFT
fCAcmDkaMSys5J3P0HQsYdMgNOR/+WL7cnAwMxeYsEy20oOh+7KxJHJqfQ4ScM5r
5/HPuhMnWalbPd8mkf739wuDw79bJHsm/E5DKMFOOrhWUjQ2sfCj1fHDYbAiCe5L
hF5W6hTPtB7RgLAoB7U+1Y6NFG3IxnwtUFjATXZE9lEhHi4lpsBDnFypF7TGzv/Z
347AbkKol4UCoQaUMSYeA4UkN8rN23DfssHYM3P4lSBW7hxpu49o+j2ovYZt/XqS
tx6pomgUE2e+MR+eVkqXfiCmHvKSQC7nHweOwTRRdFpTdvCEH0VGQThyI3s6Fgsf
chWl6PDXqF3LoNltMjzLwxBuVA590n+lFICIRLaAB2zs5nN8clKUxlH9x8Mq0/oY
T5DTxtmbHmI3m3X5uhnp19c+wDcliMmWad5nluonXFBVo9flD09UsmmoOUnid3Wx
p54V07ZRMzpXRpyJ4WQTwwd4sQJoYD/WR0OXe4aXNO6pje20Er7KSKc4Rqr8uCl9
Q0BvWDb3HQ11L+w/cgFLf2pjpr9l7JuYP6z8UokdpgcXgaR3U9U=
=jG0r
-----END PGP SIGNATURE-----
# gpg --verify data.txt.asc
gpg: Signature made Tue Jun 25 14:54:59 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
gpg: WARNING: not a detached signature; file 'data.txt' was NOT verified!
8) Ký chứng thực nhưng không kèm nội dung
Nội dung của file data.txt
sẽ không được đính kèm trong chữ ký. Người gửi cần gửi kèm cả chữ ký cả nội dung data.txt
. Sử dụng tính năng này nếu muốn gửi nội dung trong khi không bắt buộc người nhận nhất định phải chứng thực.
# gpg --detach-sign -a data.txt
File 'data.txt.asc' exists. Overwrite? (y/N) y
# cat data.txt.asc
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEoyr3OGJR1Yr5bNfFrJ8CoogPyU0FAmZ626EACgkQrJ8CoogP
yU0D6w/9HqmYPZy8H/sb5YGFX8nsylwSZTsk6mNy4dFaVNAOxK+xJFxXCFHh9fSc
C6MahN/IBqGd7YiBWbYapZ3JDcdh5Yc764AgtXaSPrTG0kklnDOYvcvB6QI8qz5Q
Nlcs9GIS4NpzbyBbWeEMBOIWJI7aVSeVi6DRxV4DJpTVc4S4BhcanQa2nBJq7/W7
tTFplYZq6ioiiLjdhDeflELwbwB75pldSAHFlzGXMsZFBbwaFKHKS+EhqXqkFHYZ
VuV1TtHfxatyPpQxqsivd0fllJp1Q6isoUEtf+F+cezpxfVs6UgZPNYd5sOhUYG1
Ph8XyS/nUygyYGh970ZC48iaFYRC+KBvjjeCRdahfc3Wr764c1ZzNbSUC+S8krgC
tiPK4rBou/L2ZEz6YkWmRrmbdCoFi8fMWu1WYT+PqE4iMilbSB3Kyemg4YCDQvH7
lHxJu6bWPJviRTDw8pWjxv4oymkPPuR7jxV9XzahaHgsxRe7XjRCXKM61/Hc30FW
jTAoBVlzjXQAxiGFLolOXjnTcJzZdbT8CHYE/cvjlB86KyF981KLMV17VJBlNh9N
OqSyK94n1YRTf2Qr9hPiI3ajwB7/XUV8LcA21Xp8t7NR6SJIA2yVmqvJEGoLpIoZ
30n40LSxr5HWsn6eTMhoQi0W0UBCTtMdaRet1GrNMPWtSFPd9bI=
=IfeT
-----END PGP SIGNATURE-----
# gpg --decrypt data.txt.asc
gpg: assuming signed data in 'data.txt'
gpg: Signature made Tue Jun 25 15:00:49 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
Câu lệnh nói rằng nội dung cần được tham khảo ở file data.txt
. Ta có thể kiểm tra tính xác thực của data.txt
như sau.
gpg --verify data.txt.asc data.txt
gpg: Signature made Tue Jun 25 15:00:49 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
9) Phục hồi dữ liệu
Nếu chữ ký có đính kèm dữ liệu, bạn có thể phục hồi dữ liệu từ chữ ký.
# ls
data.txt data.txt.asc data.txt.gpg data.txt.sig
# rm data.txt
# gpg data.txt.gpg
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: Signature made Tue Jun 25 14:45:33 2024 UTC
gpg: using RSA key A32AF7386251D58AF96CD7C5AC9F02A2880FC94D
gpg: Good signature from "GnuPG Testkey (Demo GnuPG) <testkey@local>" [ultimate]
# ls
data.txt data.txt.asc data.txt.gpg data.txt.sig
# cat data.txt
Important messages
Tóm tắt phần mở rộng
- .gpg file nhị phân (binary)
- .asc file text (ascii)
- .sig file nhị phân, chỉ bao gồm chữ ký