Hướng Dẫn Sử Dụng EJBCA — Từ Cơ Bản Đến Nâng Cao

 

Hướng Dẫn Sử Dụng EJBCA — Từ Cơ Bản Đến Nâng Cao

Tài liệu này giả định bạn đã cài đặt xong EJBCA (Community Edition) và có thể truy cập Admin Web tại https://localhost:8443/ejbca/adminweb/ bằng chứng chỉ SuperAdmin. 


1. Kiến thức nền tảng PKI

brew services start mariadb

~/opt/wildfly/bin/standalone.sh

https://localhost:8443/ejbca/adminweb/

# Ở cửa sổ đang chạy standalone.sh, bấm Ctrl+C

brew services stop mariadb 

Trước khi thao tác, cần nắm vững các khái niệm cốt lõi — đây là "ngôn ngữ" xuyên suốt toàn bộ EJBCA.

Thuật ngữ Giải thích dễ hiểu
CA (Certificate Authority) "Cơ quan cấp chứng chỉ" — thực thể có private key dùng để ký (issue) chứng chỉ cho người/thiết bị khác. Giống như con dấu của một cơ quan có thẩm quyền.
Root CA CA tự ký chính mình (self-signed) — gốc của toàn bộ chuỗi tin cậy (trust chain).
Sub CA (Intermediate CA) CA được một CA khác (thường là Root CA) ký cho, dùng để cấp chứng chỉ "cấp dưới". Giúp bảo vệ Root CA (Root CA có thể để offline, ít dùng).
CSR (Certificate Signing Request) "Đơn xin cấp chứng chỉ" — chứa public key + thông tin (CN, tổ chức...), được gửi cho CA để xin ký.
Certificate (chứng chỉ) Kết quả CA ký lên CSR — chứng minh "public key này thuộc về [tên/tổ chức] này, do CA X xác nhận".
Private Key Khóa bí mật, không bao giờ được chia sẻ — dùng để giải mã/ký số, tương ứng 1-1 với public key trong chứng chỉ.
Certificate Profile Khuôn mẫu quy định thuộc tính kỹ thuật của chứng chỉ: thời hạn, thuật toán, Key Usage, Extended Key Usage...
End Entity Profile Khuôn mẫu quy định thông tin cần khai báo khi đăng ký: CN, email, tổ chức nào là bắt buộc/tùy chọn.
End Entity Một bản ghi cụ thể — đại diện cho 1 người/thiết bị sẽ được cấp chứng chỉ.
CRL (Certificate Revocation List) Danh sách các chứng chỉ đã bị thu hồi (không còn hợp lệ dù chưa hết hạn), CA publish định kỳ.
OCSP (Online Certificate Status Protocol) Giao thức hỏi-đáp nhanh để kiểm tra 1 chứng chỉ có bị thu hồi hay không, không cần tải cả CRL.

Luồng tổng quát của toàn bộ PKI:

   [Root CA]  ──ký──▶  [Sub CA]  ──ký──▶  [Chứng chỉ End Entity]
       │                                         │
       └── Trust Anchor                          └── Dùng cho: server, người dùng, thiết bị...

2. Tổng quan giao diện EJBCA

Sau khi đăng nhập Admin Web, menu chính chia thành:

Menu Chức năng chính
CA Functions Quản lý CA, Certificate Profiles, Publishers, Validators
RA Functions Quản lý End Entity Profiles, tạo/tìm End Entity, cấp chứng chỉ
VA Functions Cấu hình OCSP, kiểm tra trạng thái chứng chỉ
Supervision Functions Audit Log, Approval Requests
System Functions Administrator Roles, phân quyền
System Configuration Cấu hình toàn hệ thống (ngôn ngữ, session, giới hạn)
RA Web Giao diện công khai cho người dùng cuối tự đăng ký (không cần chứng chỉ admin)

3. Phần cơ bản: Tạo CA đầu tiên

Bạn đã có sẵn ManagementCA (tạo tự động lúc cài đặt, dùng cho việc quản trị nội bộ). Giờ ta tạo thêm 1 CA "sản xuất" dùng để cấp chứng chỉ thật cho server/người dùng.

Ví dụ: Tạo Root CA tên CongTyRootCA

  1. Vào CA Functions → Certification Authorities
  2. Bấm nút Create CA
  3. Điền các trường:
Trường Giá trị ví dụ Giải thích
CA Name CongTyRootCA Tên nội bộ, dễ nhận diện
Subject DN CN=Cong Ty Root CA,O=Cong Ty ABC,C=VN Tên đầy đủ xuất hiện trong chứng chỉ
Validity 3650d (10 năm) Root CA nên có thời hạn dài
CA Type X509 Chuẩn phổ biến nhất
Signature Algorithm SHA256WithRSA An toàn, tương thích rộng
Key Algorithm RSA Hoặc ECDSA nếu muốn key nhỏ/nhanh hơn
Key Size 4096 Root CA nên dùng key lớn vì ít thay đổi, cần bền vững lâu dài
CA Token Soft (lưu trong keystore mềm) hoặc PKCS#11 (nếu có HSM) Môi trường dev/test dùng Soft là đủ
  1. Bấm Create — hệ thống sẽ tự sinh cặp key + tự ký chứng chỉ Root CA.

Ví dụ: Tạo Sub CA tên CongTyServerCA (được ký bởi Root CA trên)

  1. Lặp lại thao tác Create CA, nhưng:
    • CA Name: CongTyServerCA
    • Subject DN: CN=Cong Ty Server CA,O=Cong Ty ABC,C=VN
    • Signed By: chọn CongTyRootCA (thay vì tự ký)
    • Validity: 1825d (5 năm — ngắn hơn Root CA)
  2. Bấm Create

→ Giờ bạn có chuỗi: CongTyRootCA → ký → CongTyServerCA. Chứng chỉ cấp sau này nên dùng CongTyServerCA để ký, giữ CongTyRootCA "an toàn", ít động tới.


4. Certificate Profile — Khuôn mẫu chứng chỉ

Certificate Profile quy định thuộc tính kỹ thuật của chứng chỉ sẽ cấp ra — ví dụ chứng chỉ dùng để làm HTTPS server sẽ cần khác với chứng chỉ dùng để ký email.

Ví dụ: Tạo Certificate Profile cho TLS Server

  1. Vào CA Functions → Certificate Profiles
  2. Bấm Add Certificate Profile, đặt tên: TLS_Server_1Year
  3. Chọn Type: dựa trên profile có sẵn SERVER để kế thừa cấu hình chuẩn
  4. Cấu hình các trường quan trọng:
Trường Giá trị ví dụ
Validity 365d
Key Usage Digital Signature, Key Encipherment
Extended Key Usage Server Authentication
Available Key Algorithms RSA 2048, ECDSA secp256r1
Available CAs Chọn CongTyServerCA
Allow Subject Alternative Name Bật (cần cho SAN — domain phụ/IP)
  1. Bấm Save

Ví dụ: Tạo Certificate Profile cho Client Authentication (dùng cho VPN, đăng nhập nội bộ)

Tương tự trên, nhưng:

  • Extended Key Usage: Client Authentication
  • Validity: 730d (2 năm)

5. End Entity Profile — Khuôn mẫu đăng ký

Quy định thông tin cần khai báo khi tạo End Entity.

Ví dụ: Tạo End Entity Profile ServerEnrollment

  1. Vào RA Functions → End Entity Profiles
  2. Bấm Add Profile, đặt tên ServerEnrollment
  3. Cấu hình:
    • Subject DN Attributes: bật CN (bắt buộc), O, C
    • Subject Alternative Name: bật DNS Name (để nhập domain phụ)
    • Default Certificate Profile: chọn TLS_Server_1Year đã tạo ở Mục 4
    • Available CAs: chọn CongTyServerCA
    • Default Token: USERGENERATED (nếu server tự tạo CSR) hoặc P12 (nếu để EJBCA sinh key luôn)
  4. Bấm Save

6. Tạo End Entity và cấp chứng chỉ đầu tiên

Kịch bản ví dụ: Cấp chứng chỉ TLS cho web01.congty.local

Bước 1: Tạo End Entity

  1. Vào RA Functions → Add End Entity
  2. Chọn End Entity Profile: ServerEnrollment
  3. Điền:
    • Username: web01
    • Password/Confirm Password: đặt 1 mật khẩu tạm, ví dụ TamThoi123!
    • CN, Common name: web01.congty.local
    • Organization: Cong Ty ABC
    • Country: VN
    • CA: CongTyServerCA
    • Token: USERGENERATED
  4. Bấm Add

Bước 2: Tạo CSR trên server thật (nếu chọn USERGENERATED)

Trên server web01 (hoặc máy bất kỳ), chạy:

openssl req -new -newkey rsa:2048 -nodes \
  -keyout web01.key \
  -out web01.csr \
  -subj "/CN=web01.congty.local/O=Cong Ty ABC/C=VN"

Giải thích:

  • -newkey rsa:2048 = tự sinh cặp key RSA 2048-bit mới.
  • -nodes = không mã hóa private key (tiện dùng trực tiếp cho server, không cần nhập passphrase mỗi lần restart).
  • -keyout web01.key = file private key (giữ bí mật, không gửi cho ai).
  • -out web01.csr = file CSR (sẽ gửi cho EJBCA).

Bước 3: Nộp CSR và nhận chứng chỉ

  1. Vào RA Web: https://localhost:8443/ejbca/ra/
  2. Đăng nhập bằng username web01 + password TamThoi123! vừa đặt
  3. Chọn Enroll with request (hoặc tương tự tùy phiên bản UI)
  4. Dán nội dung file web01.csr vào ô yêu cầu
  5. Bấm Enroll → hệ thống trả về chứng chỉ, tải file .pem/.crt về máy

Bước 4: Cài chứng chỉ vào web server (ví dụ Nginx)

server {
    listen 443 ssl;
    server_name web01.congty.local;

    ssl_certificate     /etc/nginx/ssl/web01.crt;
    ssl_certificate_key /etc/nginx/ssl/web01.key;
    ...
}

→ Copy web01.crt (chứng chỉ vừa nhận) và web01.key (private key đã tạo ở Bước 2) vào đúng đường dẫn, reload Nginx.


7. Thu hồi chứng chỉ (Revocation) và CRL

Khi nào cần thu hồi?

  • Private key bị lộ/đánh cắp.
  • Server ngừng hoạt động, đổi domain.
  • Nhân viên rời công ty (nếu chứng chỉ dùng cho cá nhân).

Ví dụ: Thu hồi chứng chỉ của web01

  1. Vào RA Functions → Search End Entities
  2. Tìm web01 → bấm vào để mở chi tiết
  3. Trong danh sách chứng chỉ của entity này, bấm Revoke
  4. Chọn lý do (Reason Code) — các lý do phổ biến:
Reason Code Khi nào dùng
Key Compromise Private key bị lộ — nghiêm trọng nhất
Superseded Đã cấp chứng chỉ mới thay thế
Cessation of Operation Server/dịch vụ ngừng hoạt động
Unspecified Không rõ lý do cụ thể
  1. Bấm Confirm — chứng chỉ ngay lập tức được đánh dấu REVOKED trong database.

Publish CRL mới ngay lập tức (không chờ lịch tự động)

  1. Vào CA Functions → Certification Authorities
  2. Chọn CongTyServerCA → bấm Create CRL
  3. CRL mới sẽ chứa serial number của chứng chỉ web01 vừa thu hồi.

Kiểm tra CRL từ dòng lệnh

openssl crl -in congtyserverca.crl -text -noout | grep -A2 "Serial Number"

8. OCSP — Kiểm tra trạng thái chứng chỉ real-time

OCSP nhanh hơn CRL vì không cần tải cả danh sách — chỉ hỏi đúng 1 serial number.

Kiểm tra OCSP endpoint đã hoạt động

EJBCA tự động serve OCSP tại: https://localhost:8443/ejbca/publicweb/status/ocsp

Test bằng OpenSSL

openssl ocsp -issuer congtyserverca.pem \
  -cert web01.crt \
  -url https://localhost:8443/ejbca/publicweb/status/ocsp \
  -CAfile congtyrootca.pem

Kết quả trả về good, revoked, hoặc unknown tương ứng trạng thái thật của chứng chỉ.


9. Phân quyền quản trị (Roles & Access Rules)

Không nên dùng chung tài khoản SuperAdmin cho mọi việc — nên tạo role riêng theo nguyên tắc least privilege (chỉ cấp quyền vừa đủ).

Ví dụ: Tạo role "Chỉ được xem, không được cấp/thu hồi"

  1. Vào System Functions → Administrator Roles
  2. Bấm Add Role, đặt tên ReadOnlyAuditor
  3. Vào role vừa tạo, cấu hình Access Rules:
    • Bật quyền View cho CA Functions, RA Functions
    • Tắt quyền Create, Edit, Revoke
  4. Thêm thành viên (Members): chọn Add with certificate rule hoặc chọn 1 chứng chỉ cụ thể để gán vào role này

Ví dụ: Tạo admin phụ có quyền cấp chứng chỉ nhưng không được sửa CA

  1. Tạo role CertificateOperator
  2. Bật quyền: RA Functions → Full access, CA Functions → View only
  3. Tắt: quyền vào Certification Authorities → Edit/Create/Delete

10. Mô hình phân cấp CA (Root CA → Sub CA)

Đây là kiến trúc khuyến nghị cho production thật:

CongTyRootCA (10 năm, để "lạnh" — ít dùng, có thể offline)
    │
    ├── CongTyServerCA (5 năm — cấp chứng chỉ server/TLS)
    ├── CongTyClientCA (5 năm — cấp chứng chỉ client auth/VPN)
    └── CongTyCodeSignCA (5 năm — ký code/firmware)

Lợi ích của mô hình này:

  • Nếu 1 Sub CA bị lộ key, chỉ cần thu hồi Sub CA đó (thêm vào CRL của Root CA), không ảnh hưởng toàn bộ hệ thống.
  • Root CA có thể giữ offline (xuất key ra rồi tắt CA đó trên EJBCA, chỉ bật lại khi cần ký thêm 1 Sub CA mới) — giảm rủi ro bị tấn công.

Cách "đưa Root CA offline" (nâng cao)

  1. Sau khi tạo xong các Sub CA cần thiết, vào CA Functions → Certification Authorities
  2. Chọn CongTyRootCA → đổi trạng thái CA Token sang Offline (nếu dùng HSM vật lý, đơn giản là rút thiết bị ra).
  3. Chỉ kích hoạt lại khi cần ký thêm Sub CA mới hoặc publish CRL định kỳ.

11. Đăng ký tự động qua giao thức (SCEP, EST, CMP)

Dùng khi cần cấp chứng chỉ hàng loạt, tự động cho nhiều thiết bị (router, IoT, laptop công ty) mà không cần thao tác tay từng cái.

SCEP (Simple Certificate Enrollment Protocol) — phổ biến nhất cho thiết bị mạng

  1. Vào System Configuration → Protocol Configuration, đảm bảo SCEP đang Enabled
  2. Tạo 1 SCEP Alias riêng (ví dụ scep-thietbi), gán với End Entity Profile phù hợp
  3. Endpoint SCEP sẽ có dạng:
    https://localhost:8443/ejbca/publicweb/apply/scep/scep-thietbi/pkiclient.exe
    
  4. Cấu hình thiết bị (ví dụ router Cisco) trỏ tới endpoint này để tự động enroll.

EST (Enrollment over Secure Transport) — chuẩn mới hơn, bảo mật tốt hơn SCEP

Tương tự, bật tại System Configuration → Protocol Configuration → EST, endpoint dạng:

https://localhost:8443/.well-known/est/[alias]/simpleenroll

CMP (Certificate Management Protocol) — dùng nhiều trong viễn thông, telecom

Cấu hình tại System Configuration → Protocol Configuration → CMP.


12. EJBCA REST API và Web Services

Dùng để tích hợp EJBCA vào hệ thống khác (ví dụ: tự động cấp chứng chỉ khi có đơn hàng mới, tích hợp CI/CD để cấp cert cho container).

Bật REST API

Mặc định REST API đã deploy cùng ejbca.ear tại: https://localhost:8443/ejbca/ejbca-rest-api/v1

Ví dụ: Gọi API lấy trạng thái hệ thống (cần chứng chỉ client để xác thực, giống như SuperAdmin)

curl --cert superadmin.pem --key superadmin.key \
  https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/status

Ví dụ: Cấp chứng chỉ qua REST API (gửi CSR, nhận về chứng chỉ)

curl --cert superadmin.pem --key superadmin.key \
  -X POST https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/pkcs10enroll \
  -H "Content-Type: application/json" \
  -d '{
    "certificate_request": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----",
    "certificate_profile_name": "TLS_Server_1Year",
    "end_entity_profile_name": "ServerEnrollment",
    "certificate_authority_name": "CongTyServerCA",
    "username": "web02",
    "password": "TamThoi123!"
  }'

Xem đầy đủ danh sách endpoint tại: https://localhost:8443/ejbca/ejbca-rest-api/swaggerui/ (Swagger UI tự động sinh từ code, rất hữu ích để thử API trực tiếp trên trình duyệt).


13. Approval Workflow (Duyệt 4 mắt)

Dùng trong tổ chức lớn — yêu cầu 2 admin khác nhau phải đồng ý mới cho thực hiện 1 hành động nhạy cảm (ví dụ: thu hồi CA, cấp chứng chỉ Root).

Cách bật Approval cho 1 hành động cụ thể

  1. Vào CA Functions → Certification Authorities → chọn CA cần bảo vệ
  2. Mục Approval Settings: chọn hành động cần duyệt (ví dụ Revocation, Key Recovery)
  3. Gán Approval Profile quy định cần bao nhiêu admin duyệt (thường 1-2 người)

Quy trình khi có Approval bật:

  1. Admin A thực hiện hành động (ví dụ Revoke) → hệ thống tạo Approval Request, chưa thực thi ngay
  2. Admin B (khác Admin A) vào Supervision Functions → Approve Actions, xem yêu cầu, bấm Approve
  3. Lúc này hành động mới thực sự được thi hành

14. Audit Log và Giám sát

Xem lịch sử thao tác

  1. Vào Supervision Functions → Audit Log
  2. Có thể lọc theo: Admin, thời gian, loại sự kiện (CERT_ISSUED, CA_REVOKED, ACCESS_CONTROL...)

Ví dụ tình huống thực tế: Điều tra ai đã thu hồi chứng chỉ web01

  1. Vào Audit Log
  2. Lọc Event = REVOKE_CERT
  3. Tìm dòng liên quan tới web01, xem cột Administrator để biết ai thực hiện, Time để biết khi nào.

15. Ví dụ thực hành tổng hợp: Cấp TLS cho web server nội bộ

Đây là kịch bản gộp toàn bộ các bước trên thành 1 luồng hoàn chỉnh, từ đầu tới cuối.

Mục tiêu: HTTPS nội bộ cho intranet.congty.local chạy trên Nginx

Bước 1 — Chuẩn bị CA (làm 1 lần duy nhất):

  • Đã có CongTyRootCACongTyServerCA (theo Mục 3)
  • Đã có Certificate Profile TLS_Server_1Year (theo Mục 4)
  • Đã có End Entity Profile ServerEnrollment (theo Mục 5)

Bước 2 — Tạo CSR trên server Nginx:

openssl req -new -newkey rsa:2048 -nodes \
  -keyout intranet.key -out intranet.csr \
  -subj "/CN=intranet.congty.local/O=Cong Ty ABC/C=VN" \
  -addext "subjectAltName=DNS:intranet.congty.local,DNS:www.intranet.congty.local"

Bước 3 — Tạo End Entity trong EJBCA (theo Mục 6, Bước 1), nhớ bật SAN trong End Entity Profile để chấp nhận nhiều domain.

Bước 4 — Enroll qua RA Web, nộp CSR, tải chứng chỉ về

Bước 5 — Cài vào Nginx:

server {
    listen 443 ssl;
    server_name intranet.congty.local www.intranet.congty.local;
    ssl_certificate     /etc/nginx/ssl/intranet.crt;
    ssl_certificate_key /etc/nginx/ssl/intranet.key;
    ssl_trusted_certificate /etc/nginx/ssl/congtyserverca-chain.pem;
}

Bước 6 — Phân phối Root CA cho toàn bộ máy nhân viên (để trình duyệt không báo "not trusted"):

  • Export CongTyRootCA dưới dạng .crt (CA Functions → Certification Authorities → chọn CA → Download PEM)
  • Cài vào Keychain macOS/Group Policy Windows của toàn công ty, đánh dấu Trusted Root

→ Sau bước này, mọi nhân viên truy cập https://intranet.congty.local sẽ thấy ổ khóa xanh bình thường, không còn cảnh báo "Not Secure".


16. Sao lưu và phục hồi (Backup/Restore)

Những gì cần backup định kỳ:

Thành phần Đường dẫn (theo cài đặt Mac trong hướng dẫn trước) Mức độ quan trọng
Database ejbca (chứa toàn bộ CA data, chứng chỉ, log) MariaDB Cực kỳ quan trọng
CA Keystore (private key của CA) Trong database hoặc HSM Cực kỳ quan trọng — mất là mất luôn CA
File cấu hình conf/*.properties ~/ejbca-src/ejbca/conf/ Quan trọng (dễ tạo lại nếu nhớ cấu hình)

Backup database bằng mysqldump

mysqldump -u ejbca -pejbca ejbca > ejbca-backup-$(date +%Y%m%d).sql

Phục hồi

mysql -u ejbca -pejbca ejbca < ejbca-backup-20260709.sql

Khuyến nghị production: backup tự động hàng ngày bằng cron job, lưu trữ ở nơi khác server (offsite), mã hóa file backup vì nó chứa private key của CA.


17. Các lỗi thường gặp và cách khắc phục

Lỗi Nguyên nhân thường gặp Cách fix
Certificate is not trusted trên trình duyệt Root CA chưa được cài vào Trusted Store của máy/trình duyệt Export Root CA, import vào Keychain/Trust Store
CSR subject does not match End Entity Thông tin CN trong CSR khác với End Entity đã tạo Sửa lại CSR hoặc sửa lại End Entity cho khớp
Chứng chỉ cấp ra thiếu SAN (domain phụ) End Entity Profile chưa bật Subject Alternative Name Vào Profile, bật SAN, tạo lại End Entity
CRL không cập nhật dù đã Revoke Chưa bấm Create CRL thủ công, hoặc lịch tự động chưa tới Vào CA đó, bấm Create CRL ngay
Không đăng nhập được RA Web bằng username/password Sai mật khẩu đã đặt lúc tạo End Entity, hoặc entity đã ở trạng thái GENERATED (đã dùng rồi) Reset status của End Entity về NEW trong RA Functions
OCSP trả về unknown CA chưa cấu hình OCSP Signer, hoặc chứng chỉ không thuộc CA đang hỏi Kiểm tra cấu hình OCSP tại VA Functions

Tổng kết lộ trình học EJBCA

Cơ bản    → Tạo CA, Certificate Profile, End Entity Profile
           → Tạo End Entity, cấp 1 chứng chỉ thủ công qua RA Web

Trung cấp → Thu hồi chứng chỉ, publish CRL, dùng OCSP kiểm tra
           → Phân quyền admin theo vai trò (Roles & Access Rules)
           → Xây mô hình Root CA → Sub CA

Nâng cao  → Tự động hóa qua SCEP/EST/CMP cho hàng loạt thiết bị
           → Tích hợp REST API vào hệ thống nội bộ/CI-CD
           → Approval Workflow (duyệt 4 mắt) cho tổ chức lớn
           → Vận hành production: backup, HSM, Root CA offline

Tài liệu này dựa trên EJBCA Community Edition 9.3.7, môi trường cài đặt tham khảo là macOS + WildFly 39 + MariaDB theo hướng dẫn cài đặt trước đó. Một số tên menu/nút bấm có thể thay đổi nhẹ giữa các phiên bản EJBCA khác nhau.

Mới hơn Cũ hơn