Loading...

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 verify và 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ầuChi 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ường issuer, ở 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ứngNguyên nhân thường gặpCá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.crt kiể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ọcBà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