Bài 13. (Lab) Dựng CA nội bộ, ký chứng chỉ và băm file bằng OpenSSL
Khóa học CompTIA Security+ SY0-801 · Phần 1: Khái niệm bảo mật cốt lõi · Bài 13 · 🎯 Objective 1.3 · ⏱️ Thực hành khoảng 30 phút · 🧪 Có lab · 📝 5 câu kiểm tra cuối bài
🎯 Mục tiêu bài học
- Tự tay dựng một CA nội bộ và ký chứng chỉ cho một máy chủ giả lập.
- Kiểm tra chuỗi tin cậy bằng
openssl verifyvà quan sát lỗi khi chứng chỉ hết hạn. - Băm file bằng SHA-256, sửa một chữ số và thấy hash đổi hoàn toàn.
- Ký số một file, kiểm tra chữ ký, rồi thấy chữ ký vô hiệu khi nội dung bị sửa.
- Mã hóa và giải mã một file bằng AES, thấy điều gì xảy ra khi sai mật khẩu.
📎 Vị trí trong đề thi: bài này là thực hành cho Bài 9, Bài 10, Bài 11 và Bài 12. Đề thi không bắt bạn gõ lệnh OpenSSL, nhưng người đã tự làm một lần sẽ nhớ chuỗi CSR, CA, chứng chỉ và chữ ký lâu hơn nhiều.
⚠️ Chỉ dùng trong môi trường lab. Các khóa trong bài này không đặt mật khẩu bảo vệ để thao tác cho gọn. Khóa riêng của một CA thật phải được cất trong HSM hoặc ở trạng thái offline có bảo vệ (Bài 12). Đừng dùng chứng chỉ tạo ở đây cho hệ thống thật.
💡 Liên hệ thực tế: chấm dứt thói quen bấm "Vẫn tiếp tục"
Sau sự cố cảnh báo chứng chỉ ở Bài 11, giám đốc công ty chị Lan hỏi: "Công ty mình có tự cấp được chứng chỉ cho các hệ thống nội bộ không, khỏi mua?" Nam trả lời là được, bằng một CA nội bộ. Đây là tình huống minh họa, không phải vụ việc có thật.
Nam không muốn thử ngay trên hệ thống thật. Anh dựng thử trên máy của mình trong một buổi chiều: tạo CA, tạo khóa và CSR cho portal.congty.local, ký chứng chỉ, kiểm tra. Anh thử luôn cả trường hợp chứng chỉ hết hạn để xem thông báo lỗi trông ra sao, vì sáng thứ Sáu hôm đó cả phòng kế toán đã gặp lỗi này. Cuối buổi anh làm thêm một việc nhỏ: băm và ký một file báo cáo, sửa một chữ số, rồi xem điều gì xảy ra.
Bài lab này là bản thu gọn của buổi chiều đó.
🗂️ Hình 13a. Năm bước, bảy file. Khóa riêng (ca.key, server.key) không bao giờ rời khỏi chủ của nó.
🧪 Chuẩn bị
| Yêu cầu | Chi tiết |
|---|---|
| Hệ điều hành | Linux, macOS hoặc Windows có WSL |
| OpenSSL | Phiên bản 3.x. Kiểm tra bằng openssl version |
| Thư mục làm việc | Một thư mục trống, ví dụ lab-pki |
| Thời gian | Khoảng 30 phút |
Trên macOS, lệnh openssl mặc định có thể là LibreSSL và cú pháp hơi khác. Cài OpenSSL 3 bằng Homebrew (brew install openssl) và gọi đúng bản đó nếu gặp lỗi.
bash
mkdir lab-pki && cd lab-pki openssl version
Các kết quả mẫu dưới đây lấy từ lần chạy thật với OpenSSL 3.0.13. Ngày giờ, số serial và nội dung hash của bạn sẽ khác chút, điều đó bình thường.
🏛️ Phần 1: dựng CA nội bộ
Bước 1. Tạo khóa riêng của CA (4096 bit).
bash
openssl genrsa -out ca.key 4096
Bước 2. Tạo chứng chỉ Root CA tự ký, hiệu lực 10 năm.
bash
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -subj "/C=VN/O=VNExperts Lab/CN=VNExperts Lab Root CA" \ -out ca.crt
Bạn vừa có hai file: ca.key (khóa riêng, giữ kín) và ca.crt (chứng chỉ Root CA, có thể phân phát cho mọi máy cần tin CA này). -x509 cho OpenSSL biết hãy tạo chứng chỉ tự ký thay vì một yêu cầu CSR.
🖥️ Phần 2: tạo khóa và CSR cho máy chủ
Bước 3. Tạo khóa riêng cho máy chủ (2048 bit).
bash
openssl genrsa -out server.key 2048
Bước 4. Tạo CSR chứa khóa công khai và thông tin định danh.
bash
openssl req -new -key server.key \ -subj "/C=VN/O=Cong ty Lab/CN=portal.congty.local" \ -out server.csr
Bước 5. Kiểm tra CSR.
bash
openssl req -in server.csr -noout -subject -verify
Kết quả mẫu:
text
Certificate request self-signature verify OK subject=C = VN, O = Cong ty Lab, CN = portal.congty.local
CSR được ký bằng khóa riêng của máy chủ để chứng tỏ người gửi đang giữ khóa riêng tương ứng, nhưng chính khóa riêng thì không nằm trong file này.
✍️ Phần 3: CA ký chứng chỉ
Bước 6. Tạo file cấu hình mở rộng để ghi tên miền vào trường SAN (Bài 11).
bash
cat > server.ext <<'EOF' subjectAltName=DNS:portal.congty.local keyUsage=digitalSignature,keyEncipherment extendedKeyUsage=serverAuth basicConstraints=CA:FALSE EOF
Bước 7. CA ký CSR, hiệu lực 365 ngày.
bash
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -out server.crt -days 365 -sha256 -extfile server.ext
Kết quả mẫu:
text
Certificate request self-signature ok subject=C = VN, O = Cong ty Lab, CN = portal.congty.local
subjectở đây chỉ là thông tin được sao chép từ CSR. CA không đổi nó mà chỉ ký xác nhận. Tên CA nằm ở trườngissuer, ở bước 8.
Bước 8. Xem nội dung chứng chỉ.
bash
openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltName
Kết quả mẫu:
text
subject=C = VN, O = Cong ty Lab, CN = portal.congty.local
issuer=C = VN, O = VNExperts Lab, CN = VNExperts Lab Root CA
notBefore=Oct 21 00:30:11 2026 GMT
notAfter=Oct 21 00:30:11 2027 GMT
X509v3 Subject Alternative Name:
DNS:portal.congty.local
Hãy đối chiếu với Bài 11: subject là danh tính máy chủ, issuer là CA đã ký, hai mốc thời gian là thời hạn hiệu lực, SAN là danh sách tên miền được chứng nhận.
Bước 9. Kiểm tra chuỗi tin cậy.
bash
openssl verify -CAfile ca.crt server.crt
text
server.crt: OK
Bước 10. Giả lập chứng chỉ hết hạn. Chúng ta cho OpenSSL "nhìn" vào 400 ngày sau, khi chứng chỉ 365 ngày đã hết hạn.
bash
openssl verify -CAfile ca.crt -attime $(date -d '+400 days' +%s) server.crt
text
C = VN, O = Cong ty Lab, CN = portal.congty.local error 10 at 0 depth lookup: certificate has expired error server.crt: verification failed
Đây chính là lỗi mà cả phòng kế toán gặp ở Bài 11. Trên macOS, thay date -d '+400 days' +%s bằng date -v+400d +%s.
#️⃣ Phần 4: băm file và ký số
Bước 11. Tạo file mẫu và băm.
bash
echo "Bao cao thue Q3: 1.250.000.000" > baocao.txt sha256sum baocao.txt openssl dgst -sha256 baocao.txt
text
4a852361e57ba497d0f27f472458222098b5f899cfc12bd096feddd2778cbc51 baocao.txt SHA2-256(baocao.txt)= 4a852361e57ba497d0f27f472458222098b5f899cfc12bd096feddd2778cbc51
Hai lệnh cho cùng một giá trị. Trên macOS dùng shasum -a 256 baocao.txt thay cho sha256sum.
Bước 12. Sao lưu bản gốc, sửa một chữ số và băm lại.
bash
cp baocao.txt baocao.goc sed -i 's/1.250.000.000/1.250.000.001/' baocao.txt sha256sum baocao.txt
text
f90b1ca696225ff963fce549963ff94fa8c40a3181bfde9530829308dda51378 baocao.txt
Chỉ đổi một chữ số, hash khác hoàn toàn (hình 10a ở Bài 10). Trên macOS dùng sed -i '' thay cho sed -i. Sau đó khôi phục file gốc: cp baocao.goc baocao.txt.
Bước 13. Ký file bằng khóa riêng của máy chủ.
bash
openssl dgst -sha256 -sign server.key -out baocao.sig baocao.txt ls -l baocao.sig
Chữ ký có kích thước 256 byte, đúng bằng độ dài khóa RSA 2048 bit.
Bước 14. Lấy khóa công khai từ chứng chỉ và kiểm tra chữ ký.
bash
openssl x509 -in server.crt -pubkey -noout > server.pub openssl dgst -sha256 -verify server.pub -signature baocao.sig baocao.txt
text
Verified OK
Bước 15. Sửa file rồi kiểm tra lại.
bash
sed -i 's/1.250.000.000/1.250.000.001/' baocao.txt openssl dgst -sha256 -verify server.pub -signature baocao.sig baocao.txt
text
Verification failure
OpenSSL còn in thêm vài dòng lỗi chi tiết ("bad signature"). Điều quan trọng là dòng cuối: chữ ký không còn khớp với nội dung đã bị sửa.
🔍 Hình 13b. Cùng một chữ ký, hai kết quả khác nhau. Chữ ký gắn với nội dung gốc chứ không gắn với tên file.
🔒 Phần 5 (làm thêm): mã hóa đối xứng bằng AES
Khôi phục file gốc rồi mã hóa bằng AES-256, mật khẩu dùng để sinh khóa.
bash
cp baocao.goc baocao.txt openssl enc -aes-256-cbc -pbkdf2 -salt -in baocao.txt -out baocao.enc -pass pass:LabMatKhau123 openssl enc -d -aes-256-cbc -pbkdf2 -in baocao.enc -pass pass:LabMatKhau123
text
Bao cao thue Q3: 1.250.000.000
Giải mã bằng mật khẩu sai:
bash
openssl enc -d -aes-256-cbc -pbkdf2 -in baocao.enc -pass pass:SaiMatKhau
text
bad decrypt
OpenSSL báo bad decrypt và chỉ in ra dữ liệu rác. Hai điểm đáng chú ý: -salt thêm một giá trị ngẫu nhiên nên cùng một file mã hóa hai lần cho hai kết quả khác nhau, và -pbkdf2 là bước key stretching biến mật khẩu thành khóa (Bài 10). Cách ghi mật khẩu trực tiếp trên dòng lệnh chỉ dùng cho lab, vì nó để lại dấu vết trong lịch sử lệnh.
🧹 Dọn dẹp và bước tiếp theo
bash
cd .. && rm -rf lab-pki
Nếu muốn các máy tin CA này, bạn cài ca.crt vào kho tin cậy (trust store). Trên Windows, ví dụ với quyền quản trị: certutil -addstore -f "Root" ca.crt. Trong doanh nghiệp, việc này thường được đẩy hàng loạt bằng chính sách nhóm. Cài một Root CA nghĩa là bạn trao toàn quyền tin cậy cho nó, nên chỉ cài CA mà bạn kiểm soát và bảo vệ được.
🛠️ Gỡ lỗi thường gặp
| Triệu chứng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
openssl: command not found |
Chưa cài OpenSSL | Cài OpenSSL 3.x |
Lỗi với -ext hoặc -addext |
Bản OpenSSL cũ hoặc LibreSSL | Dùng OpenSSL 3.x |
date: illegal option -- d |
Đang dùng macOS | Dùng date -v+400d +%s |
verify báo unable to get local issuer certificate |
Thiếu -CAfile ca.crt hoặc sai file CA |
Kiểm tra lại đường dẫn tới ca.crt |
| Verification failure dù chưa sửa file | File bị đổi dấu xuống dòng hoặc sửa nhầm | Khôi phục từ baocao.goc rồi ký lại |
📌 Tóm tắt nhanh
- Chuỗi tạo chứng chỉ: khóa riêng, CSR, CA ký, chứng chỉ. Khóa riêng không rời khỏi chủ của nó.
openssl verify -CAfile ca.crt server.crtkiểm tra chuỗi tin cậy. Chứng chỉ quá hạn bị từ chối.- Hash đổi hoàn toàn khi sửa một chữ số. Chữ ký số chỉ khớp với nội dung gốc.
- AES giải mã sai mật khẩu cho ra
bad decrypt. Salt và key stretching làm kết quả khó đoán.
💬 Hỏi & Đáp nhanh
❓ Tôi có cần thực hành lab này mới thi đỗ không? Không bắt buộc. Đề thi Security+ không yêu cầu gõ lệnh OpenSSL. Nhưng người đã tự tay đi một vòng thường nhớ chắc quan hệ giữa khóa, CSR, chứng chỉ và chữ ký.
❓ Vì sao khóa riêng của CA lại phải bảo vệ nghiêm hơn khóa máy chủ? Ai có khóa riêng của CA thì ký được chứng chỉ cho bất kỳ tên miền nào, và mọi máy tin CA đó sẽ tin chứng chỉ giả. Vì thế khóa Root CA được giữ offline hoặc trong HSM (Bài 12).
❓ Chứng chỉ do CA nội bộ có dùng được cho website công cộng không? Không. Trình duyệt của người ngoài công ty không có CA của bạn trong kho tin cậy, nên sẽ cảnh báo. CA nội bộ chỉ phù hợp cho hệ thống nội bộ mà tổ chức quản lý được kho tin cậy.
📝 Bài tập đánh giá
Tự chọn đáp án cho từng câu, rồi đối chiếu với phần đáp án ở cuối bài.
Câu 1. Trong lab, file nào chứa khóa công khai của máy chủ và được gửi cho CA để xin ký?
- A. server.key
- B. server.csr
- C. ca.key
- D. baocao.sig
Câu 2. Lệnh openssl verify -CAfile ca.crt server.crt trả về server.crt: OK. Điều này cho biết gì?
- A. Chứng chỉ máy chủ được ký bởi CA đó và còn hiệu lực
- B. Khóa riêng của máy chủ đã bị lộ
- C. File baocao.txt chưa bị sửa
- D. Chứng chỉ không có SAN
Câu 3. Sau khi sửa một chữ số trong file đã ký, kiểm tra chữ ký báo Verification failure. Nguyên nhân là gì?
- A. Khóa công khai bị hỏng
- B. Hash của nội dung mới không còn khớp với hash đã được ký
- C. CA đã thu hồi chứng chỉ
- D. File được mã hóa sai thuật toán
Câu 4. Khi tạo chữ ký ở bước 13, khóa nào được dùng để ký?
- A. Khóa công khai của máy chủ
- B. Khóa riêng của máy chủ
- C. Khóa công khai của CA
- D. Mật khẩu AES
Câu 5. Giải mã file AES bằng mật khẩu sai cho kết quả bad decrypt. Điều này minh họa nguyên tắc nào?
- A. Không có khóa đúng thì không đọc được bản rõ
- B. AES là hàm băm một chiều
- C. Mọi mật khẩu đều giải mã được
- D. Chữ ký số tự sửa lỗi
👉 Đáp án
Câu 1: B — CSR chứa khóa công khai và thông tin định danh, gửi cho CA. Khóa riêng (server.key) không bao giờ gửi đi.
Câu 2: A — Kết quả OK nghĩa là chuỗi ký dẫn về CA đã tin và chứng chỉ còn hiệu lực tại thời điểm kiểm tra.
Câu 3: B — Chữ ký được tạo từ hash của nội dung gốc. Nội dung đổi thì hash đổi và không còn khớp.
Câu 4: B — Ký bằng khóa riêng của máy chủ, kiểm tra bằng khóa công khai lấy từ chứng chỉ.
Câu 5: A — Mã hóa đối xứng bảo vệ tính bí mật: thiếu khóa đúng thì chỉ thu được dữ liệu rác.
📚 Bài viết thuộc khóa học CompTIA Security+ của VNExperts
🧭 Điều hướng
| ⬅️ Bài trước | 🏠 Mục lục khóa học | Bài kế tiếp ➡️ |
|---|---|---|
| Bài 12: Quản lý khóa và phần cứng bảo mật: KMS, HSM, TPM, secure enclave | Mục lục khóa học CompTIA Security+ | Bài 14: Ôn tập Phần 1 + Quiz tổng hợp 15 câu |