Hồ sơ tích hợp — Ký số chuyên dùng công vụ VGCA v2.0
Bấm nút bên phải → chọn "Save as PDF"

HỒ SƠ TÍCH HỢP
KÝ SỐ CHUYÊN DÙNG CÔNG VỤ VGCA

Hệ thống HUP E-Document
TRƯỜNG ĐẠI HỌC DƯỢC HÀ NỘI

Nền tảng: Base44 (BaaS)

Nhà cung cấp: VGCA — Cục Cơ yếu, Chính phủ

Ngày lập: 14/09/2026

Phiên bản: 2.0

PHẦN A — TÍCH HỢP KÝ SỐ MPKI REMOTE (GỌI API + WEBHOOK)

A1. Kiến trúc tổng quan & Sơ đồ luồng dữ liệu

┌─────────────┐      1. Bấm "Ký số MPKI"        ┌──────────────────┐
│  Trình duyệt │ ──────────────────────────────▶ │  Backend Function │
│  (Frontend)  │                                │   mpkiSign         │
│  React App   │                                │  (Base44 Runtime)  │
└──────┬───────┘                                └────────┬───────────┘
       │                                                 │ 2. Lấy access_token
       │                                                 │    (client_credentials)
       │                                                 ▼
       │                                       ┌────────────────────┐
       │                                       │  VGCA API (OAuth)   │
       │                                       │  /oauth/token       │
       │                                       └────────┬───────────┘
       │                                                 │ 3. Tạo giao dịch ký
       │                                                 ▼
       │                                       ┌────────────────────┐
       │ 4. Tạo bản ghi DigitalSignature        │ VGCA API           │
       │    (trạng thái: Đang chờ)              │ /api/v1/signing/   │
       │    + callback_url = WEBHOOK_URL        │  transactions      │
       │                                       └────────┬───────────┘
       │                                                 │
       ◀────────────── 5. Trả transactionId ────────────┘
       │
       │ 6. App VGCA-Sign trên điện thoại nhận thông báo → người ký duyệt
       │    (polling dự phòng mỗi 5s + realtime subscription)
       │
       │                                  ┌────────────────────┐
       │   7. VGCA gọi Webhook về hệ thống│ VGCA Server         │
       │      POST /functions/mpkiWebhook │ (push kết quả ký)   │
       │      Header: X-VGCA-Signature      └────────┬───────────┘
       │                                           │
       ▼                                           ▼
┌─────────────┐                          ┌────────────────────┐
│  Frontend   │◀── realtime update ─────│  mpkiWebhook        │
│  cập nhật   │   (entity subscribe)     │  - Verify HMAC      │
│  trạng thái │                          │  - Map trạng thái   │
└─────────────┘                          │  - completeSignature│
                                         │  - →processSigning  │
                                         └────────────────────┘

Các thành phần hệ thống

Thành phầnVai trò
MpkiSignButton (Frontend)Nút bấm khởi tạo phiên ký, hiển thị trạng thái, polling dự phòng
mpkiSign (Backend function)Tạo giao dịch ký trên VGCA + tạo bản ghi DigitalSignature
mpkiCheckStatus (Backend function)Polling trạng thái giao dịch từ VGCA (dự phòng khi webhook chậm)
mpkiWebhook (Backend function)Nhận callback từ VGCA, xác thực HMAC, hoàn tất phiên ký
mpkiTestConnection (Backend function)Kiểm tra kết nối VGCA (admin)
mpki.ts (Shared module)Logic dùng chung: auth, tạo/tra cứu giao dịch, map trạng thái, HMAC
Entity DigitalSignatureLưu trữ phiên ký + file đã ký + metadata chứng thư

A2. Danh sách API gọi tới VGCA

Lưu ý quan trọng: Các endpoint/payload dưới đây là cấu trúc tham chiếu theo chuẩn VGCA MPKI. Khi Ban Cơ yếu cấp tài liệu API chính thức, hệ thống sẽ điều chỉnh chính xác tên trường/endpoint theo đúng đặc tả. Toàn bộ logic tập trung trong base44/shared/mpki.ts nên chỉ cần sửa 1 file.

A2.1. Lấy access token (OAuth 2.0 — Client Credentials)

MethodPOST
Endpoint{VGCA_MPKI_API_ENDPOINT}/oauth/token
Content-Typeapplication/json
Body{ "grant_type": "client_credentials", "client_id": "{CLIENT_ID}", "client_secret": "{CLIENT_SECRET}" }
Response{ "access_token": "...", "expires_in": ... }
Auth scopeServer-to-server (không liên quan user cuối)

A2.2. Tạo giao dịch ký (Create Signing Transaction)

MethodPOST
Endpoint{VGCA_MPKI_API_ENDPOINT}/api/v1/signing/transactions
AuthorizationBearer {access_token}
Body{ "file_url": "...", "document_title": "...", "signer_name": "...", "reference": "...", "callback_url": "https://hup-e-document-primary.base44.app/functions/mpkiWebhook" }
Response{ "transaction_id": "..." }

A2.3. Tra cứu trạng thái giao dịch (dự phòng)

MethodGET
Endpoint{VGCA_MPKI_API_ENDPOINT}/api/v1/signing/transactions/{transaction_id}
Response{ "status": "PENDING|COMPLETED|FAILED|REJECTED", "signed_file_url": "..." }

Polling chạy mỗi 5 giây từ frontend, tối đa 5 phút (mpki_poll_expires_at), sau đó chỉ còn dựa vào webhook.

A3. Xử lý Webhook từ VGCA

A3.1. Endpoint nhận webhook

POST https://hup-e-document-primary.base44.app/functions/mpkiWebhook

A3.2. Xác thực webhook (HMAC-SHA256)

  1. Lấy header X-VGCA-Signature (chữ ký HMAC do VGCA tạo).
  2. Tính HMAC-SHA256(webhook_secret, raw_body) bằng VGCA_MPKI_WEBHOOK_SECRET.
  3. So sánh bằng hàm timingSafeEqualHex (hằng-thời gian, chống timing attack).
  4. Không khớp → trả 401 Unauthorized.
const expected = await hmacSha256Hex(config.webhookSecret, bodyText);
if (!timingSafeEqualHex(signature.toLowerCase(), expected.toLowerCase())) {
  return Response.json({ error: 'Chữ ký webhook không hợp lệ' }, { status: 401 });
}

A3.3. Payload webhook (dự kiến)

{
  "transaction_id": "VGCA-XXXX",
  "status": "COMPLETED",
  "signed_file_url": "https://...",
  "failure_reason": "..."
}

A3.4. Luồng xử lý webhook

  1. Xác thực HMAC (như trên).
  2. Parse transaction_id → tìm bản ghi DigitalSignature tương ứng.
  3. Nếu phiên đã kết thúc (Đã ký/Ký thất bại) → bỏ qua (idempotent, chống xử lý trùng).
  4. Map trạng thái VGCA → trạng thái nội bộ:
    • PENDING → "Đang chờ duyệt trên điện thoại"
    • COMPLETED → "Đã ký"
    • FAILED/REJECTED → "Ký thất bại"
  5. Gọi completeSignature:
    • Cập nhật mpki_status, signed_file_url, signature_status = "Hợp lệ", signed_at.
    • Tự động gọi processSigningApproval để hoàn tất luồng trình ký nội bộ.
  6. Frontend nhận cập nhật theo thời gian thực qua entity subscription → đóng dialog, hiển thị file đã ký.

A3.5. Idempotency & dự phòng

Webhook và polling không xung đột: nếu webhook đến trước, polling thấy terminal=true sẽ dừng; nếu polling đến trước, webhook thấy trạng thái đã kết thúc sẽ skipped. Polling là cơ chế dự phòng (fallback) đảm bảo hệ thống vẫn cập nhật ngay cả khi VGCA không gọi webhook hoặc webhook bị mất.

A4. Bảo mật & Quản lý credentials

A4.1. Lưu trữ credentials (Secrets)

Toàn bộ credentials VGCA lưu trong Secrets của app Base44 (không hardcode trong code):

Tên secretMô tả
VGCA_MPKI_CLIENT_IDClient ID do Ban Cơ yếu cấp
VGCA_MPKI_CLIENT_SECRETClient Secret do Ban Cơ yếu cấp
VGCA_MPKI_API_ENDPOINTBase URL API VGCA (vd: https://api.vgca.gov.vn)
VGCA_MPKI_WEBHOOK_SECRETSecret dùng verify chữ ký HMAC webhook

A4.2. Chế độ Mock (thử nghiệm)

Khi chưa có credentials thật (isMock = true), hệ thống tự chạy chế độ thử nghiệm: phiên ký tự "Đã ký" sau 10 giây, toàn bộ luồng UI/luồng trình ký hoạt động bình thường — cho phép UAT ngay lập tức mà không cần chờ key. Khi điền key vào Secrets, hệ thống tự động chuyển sang production.

A4.3. Phân quyền

A5. Mô hình dữ liệu — Entity DigitalSignature

Mỗi phiên ký tạo 1 bản ghi, lưu trữ đầy đủ metadata:

TrườngMô tả
mpki_transaction_idMã giao dịch VGCA (tra cứu)
mpki_statusChờ ký / Đang chờ duyệt trên điện thoại / Đã ký / Ký thất bại
mpki_provider"VGCA-MPKI"
mpki_initiated_at / mpki_completed_atThời điểm tạo / hoàn tất
mpki_failure_reasonLý do thất bại / hủy
mpki_poll_expires_atHạn polling dự phòng
original_file_urlLink file PDF gốc (trước ký)
signed_file_urlLink file PDF đã ký (sau ký)
signer_name / signer_id / signer_roleThông tin người ký
document_id / document_type / document_title / document_numberVăn bản liên quan
signing_request_idLiên kết phiếu trình ký nội bộ
source_entity_type / source_entity_idEntity gốc chứa file PDF
certificate_serial / certificate_issuerThông tin chứng thư số
signature_statusHợp lệ / Hết hạn / Bị thu hồi / Chờ xác thực
signed_atThời điểm ký thành công

PHẦN B — LUỒNG TRÌNH KÝ NỘI BỘ (SigningRequest → BGH → Ký số)

B1. Tổng quan

Hệ thống triển khai luồng trình ký đa cấp theo mô hình trường đại học:

Người soạn thảo  →  Trưởng phòng  →  Phó Hiệu trưởng  →  Hiệu trưởng
   (Draft)            (Cấp 0)           (Cấp 1)            (Cấp 2 — cuối)

Mỗi cấp ký tạo một SigningRequest. Các phiếu cùng một văn bản được gom nhóm bằng chain_key và sắp xếp theo level (0, 1, 2...). Tại mỗi cấp, người ký có 3 lựa chọn: Ký duyệt (approve), Từ chối (reject), hoặc Yêu cầu bổ sung (request_more).

B2. Sơ đồ luồng trình ký

┌─────────────────────────────────────────────────────────────────┐
│  NGƯỜI SOẠN THẢO (Văn thư / Cán bộ đơn vị)                        │
│  1. Soạn thảo dự thảo (DocumentDraft)                             │
│  2. Chọn chuỗi ký: Trưởng phòng → Phó HT → HT                     │
│  3. Đính kèm file PDF + nộp trình ký                              │
│     → Tạo SigningRequest cấp 0 (Chờ ký)                          │
│     + SigningRequest cấp 1, 2 (Chờ duyệt — xếp hàng)              │
│     (cùng chain_key, level 0/1/2)                                 │
└──────────────────────┬──────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────────┐
│  TRƯỞNG PHÒNG (Cấp 0 — signer_role: "Trưởng phòng")              │
│  Nhận thông báo → xem văn bản                                     │
│  ┌─────────────┐  ┌─────────────┐  ┌──────────────────────┐     │
│  │  Ký duyệt   │  │  Từ chối     │  │  Yêu cầu bổ sung     │     │
│  │  (approve)  │  │  (reject)    │  │  (request_more)      │     │
│  └──────┬──────┘  └──────┬───────┘  └──────────┬───────────┘     │
└─────────┼────────────────┼─────────────────────┼────────────────┘
          │                │                     │
     [approve]        [reject]            [request_more]
          │                │                     │
          │    ┌───────────┘                     │
          │    │ Hủy toàn bộ cấp còn lại          │ Trả draft về
          │    │ Draft → "Đang soạn"             │ "Đang soạn"
          │    │ Thông báo người trình           │
          │    └────────────────────────         │
          ▼                                     ▼
┌─────────────────────────────────────────────────────────────────┐
│  processSigningApproval (Backend)                                │
│  • Tạo DigitalSignature (certificate_serial, signature_hash)     │
│  • Tìm cấp kế tiếp (Chờ duyệt, level > hiện tại)                 │
│    → chuyển sang "Chờ ký" + thông báo người ký kế tiếp           │
│  • Nếu là cấp CUỐI → finalise văn bản gốc:                       │
│    - OutgoingDocument → "Đã vào sổ"                              │
│    - InternalDocument → "Đã phát hành"                           │
│    - DocumentDraft → "Đã trình ký"                               │
│    + Email Outlook cho người trình + thông báo admin             │
└──────────────────────┬──────────────────────────────────────────┘
                       │ (cấp kế tiếp = Chờ ký)
                       ▼
┌─────────────────────────────────────────────────────────────────┐
│  PHÓ HIỆU TRƯỞNG (Cấp 1 — signer_role: "Phó Hiệu trưởng")        │
│  Cùng luồng: approve / reject / request_more                     │
│  → approve → chuyển HT (cấp 2)                                  │
└──────────────────────┬──────────────────────────────────────────┘
                       │ (cấp kế tiếp = Chờ ký)
                       ▼
┌─────────────────────────────────────────────────────────────────┐
│  HIỆU TRƯỞNG (Cấp 2 — signer_role: "Hiệu trưởng" — CẤP CUỐI)     │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  KÝ SỐ VGCA                                              │   │
│  │  • Bấm "Ký số MPKI" → mpkiSign → VGCA tạo transaction    │   │
│  │  • App VGCA-Sign trên điện thoại → duyệt                  │   │
│  │  • Webhook/polling → completeSignature                   │   │
│  │  • processSigningApproval (approve) — cấp cuối:          │   │
│  │    - Tạo DigitalSignature (file đã ký)                    │   │
│  │    - Finalise văn bản gốc ("Đã vào sổ" / "Đã phát hành")  │   │
│  │    - Email + thông báo hoàn thành chuỗi ký                │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

B3. Trạng thái SigningRequest & chuyển trạng thái

Trạng tháiÝ nghĩa
Chờ kýĐang chờ cấp này ký (cấp hiện tại active)
Chờ duyệtXếp hàng chờ cấp trước ký xong (chưa đến lượt)
Đã kýCấp này đã ký duyệt
Từ chốiCấp này từ chối ký
Yêu cầu bổ sungCấp này yêu cầu bổ sung thông tin

B4. Cấu trúc chuỗi ký (signing_chain)

Khi nộp trình ký, người soạn chọn kế hoạch chuỗi ký — lưu dạng JSON trong trường signing_chain:

[
  { "role": "Trưởng phòng", "signer_id": "user-001", "signer_name": "Nguyễn Văn A" },
  { "role": "Phó Hiệu trưởng", "signer_id": "user-002", "signer_name": "Trần Thị B" },
  { "role": "Hiệu trưởng", "signer_id": "user-003", "signer_name": "Lê Văn C" }
]

Hệ thống tự tạo N bản ghi SigningRequest (N = số cấp), cùng chain_key, level 0→N-1. Cấp 0 = Chờ ký, các cấp còn lại = Chờ duyệt.

B5. Tích hợp ký số VGCA ở cấp cuối

Khi người ký ở cấp cuối (thường là Hiệu trưởng) chọn "Ký số MPKI" thay vì "Ký duyệt" thủ công:

  1. mpkiSign tạo giao dịch VGCA → bản ghi DigitalSignature liên kết signing_request_id.
  2. Người ký duyệt trên app VGCA-Sign.
  3. Webhook/polling → completeSignature → cập nhật file đã ký.
  4. completeSignature tự gọi processSigningApproval(action="approve") → finalise văn bản gốc + email + thông báo.

Điều này đảm bảo chữ ký số VGCA và luồng phê duyệt nội bộ liên thông — không cần thao tác thủ công thứ hai.

PHẦN C — SẴN SÀNG UAT

Hạng mụcTrạng thái
Backend functions (mpkiSign, mpkiCheckStatus, mpkiWebhook, mpkiTestConnection, processSigningApproval)✅ Đã viết
Shared module mpki.ts (auth, tạo/tra cứu giao dịch, HMAC)✅ Đã viết
Frontend (nút Ký số MPKI, dialog trạng thái, polling, realtime)✅ Đã viết
Entity DigitalSignature + SigningRequest✅ Đã tạo
Luồng trình ký đa cấp (Trưởng phòng → Phó HT → HT)✅ Đã triển khai
Chế độ Mock (test UI không cần key)✅ Đang chạy
Webhook endpoint + xác thực HMAC✅ Đã viết
Panel quản trị (SystemAdmin → MPKI)✅ Đã viết
USB Token signing — plugin localhost API + UsbTokenSignPanel✅ Đã viết (v2.0)
Backend functions: usbTokenSign, checkCertificateStatus, getTimestampToken✅ Đã viết (v2.0)
Shared module: certificateValidation.ts (OCSP/CRL + TSA)✅ Đã viết (v2.0)
Entity DigitalSignature: signing_method, certificate_status, tsp_token...✅ Đã cập nhật (v2.0)
Panel quản trị: cấu hình USB Port, OCSP, CRL, TSA + nút Test✅ Đã viết (v2.0)

Cần từ Ban Cơ yếu

Cập nhật v2.0: Đổi tên đặc tả thành "Tích hợp ký số chuyên dùng công vụ VGCA" (bao hàm MPKI remote + USB Token + OCSP/CRL + TSA). Bổ sung yêu cầu cho USB Token (ký tại chỗ), OCSP/CRL (kiểm tra chứng thư) và TSA (dấu thời gian tin cậy) — đảm bảo pháp lý đầy đủ theo Điều 28, Nghị định 130/2018/NĐ-CP.

A. Ký số MPKI remote (đã có — Phần A)

  1. Client ID + Client Secret (OAuth client_credentials).
  2. API Endpoint base URL VGCA MPKI production.
  3. Webhook Secret (để verify HMAC) — hoặc xác nhận cơ chế xác thực webhook VGCA sử dụng.
  4. Tài liệu API chính thức (nếu có) — để căn chỉnh chính xác tên trường/endpoint trong mpki.ts.
  5. Đăng ký webhook URL https://hup-e-document-primary.base44.app/functions/mpkiWebhook tại VGCA (nếu VGCA yêu cầu whitelist).

B. USB Token — ký tại chỗ (Phần D)

  1. VGCA Sign Tool (plugin trình duyệt) — phần mềm trung gian giao tiếp USB Token qua PKCS#11/CSP, cung cấp localhost API.
  2. Tài liệu API localhost — đặc tả endpoints /health, /certificates, /sign (request/response format).
  3. Link tải plugin chính thức cho Windows/macOS/Linux.
  4. Hệ điều hành & trình duyệt được hỗ trợ (Chrome, Firefox, Edge, Cốc Cốc...).

C. OCSP/CRL — kiểm tra hiệu lực chứng thư (Phần E)

  1. OCSP Endpoint — URL tra cứu trạng thái chứng thư theo thời gian thực (RFC 6960).
  2. CRL Endpoint — URL tải danh sách chứng thư bị thu hồi (RFC 5280) — dùng khi OCSP không khả dụng.
  3. Định dạng truy vấn — request/response format (JSON/DER/PEM), tên trường serial/issuer.

D. TSA — dấu thời gian tin cậy (Phần F)

  1. TSA Endpoint — URL dịch vụ dấu thời gian theo RFC 3161.
  2. Định dạng truy vấn — timestamp-query (application/timestamp-query) và timestamp-response (application/timestamp-reply).
  3. Chi phí (nếu có) — mỗi request timestamp có tính phí không.

Sau khi có thông tin, admin cấu hình tại SystemAdmin → MPKI → Cấu hình USB Token & Kiểm tra chứng thư → bấm Test từng dịch vụ → toàn bộ hệ thống chuyển sang production.

PHẦN D — KÝ SỐ USB TOKEN TẠI CHỖ (PLUGIN TRÌNH DUYỆT CỤC BỘ)

D1. Kiến trúc tổng quan

Hệ thống hỗ trợ song song 2 phương thức ký số ở cấp cuối (Hiệu trưởng): MPKI remote (ký qua app điện thoại — Phần A) và USB Token (ký tại chỗ — Phần D). Người ký tự chọn phương thức phù hợp.

┌─────────────┐                                ┌─────────────────────┐
│  Trình duyệt │  1. Bấm "Ký bằng USB Token"   │  VGCA Sign Tool     │
│  (Frontend)  │ ─────────────────────────────▶│  (Plugin cục bộ)    │
│  React App   │                                │  http://127.0.0.1    │
└──────┬───────┘                                │  :{VGCA_USB_LOCAL_PORT}        │
       │                                         └────────┬────────────┘
       │ 2. GET /api/health (kiểm tra plugin)             │
       │ 3. GET /api/certificates (đọc chứng thư)          │
       │ 4. POST /api/sign (truyền file_url + cert + PIN) │
       │                                                    │
       │                                          ┌────────┴────────────┐
       │                                          │  USB Token (PKCS#11) │
       │                                          │  hoặc CSP            │
       │                                          └────────┬────────────┘
       │                                                   │ 5. Ký file PDF
       │                                                   │    tại chỗ
       │                                                   ▼
       │ 6. Trả về file đã ký (base64 hoặc URL)   ┌────────────────────┐
       │◀──────────────────────────────────────────│  File PDF đã ký     │
       │                                          └────────────────────┘
       │
       │ 7. Upload file đã ký lên lưu trữ (UploadPublicFile)
       │ 8. Gọi usbTokenSign (backend)
       │    → Tạo DigitalSignature (signing_method='usb_token')
       │    → Kiểm tra chứng thư (OCSP/CRL) — Phần E
       │    → Lấy dấu thời gian (TSA) — Phần F
       │    → Gọi processSigningApproval (finalise văn bản)
       ▼
┌────────────────────┐
│  Văn bản gốc        │
│  → "Đã vào sổ"     │
│  → Email + thông báo│
└────────────────────┘

D2. Plugin VGCA Sign Tool — Localhost API

Lưu ý: Plugin VGCA Sign Tool là phần mềm do Ban Cơ yếu cung cấp, cài đặt trên máy người dùng. Hệ thống chỉ gọi localhost API — không trực tiếp giao tiếp USB Token. Giao tiếp PKCS#11/CSP do plugin xử lý nội bộ.
EndpointMethodMô tả
/api/healthGETKiểm tra plugin đang chạy — trả về { "running": true, "version": "1.x", "name": "VGCA Sign Tool" }
/api/certificatesGETĐọc danh sách chứng thư từ USB Token — trả về { "certificates": [{ "serial", "subject", "issuer", "validTo" }] }
/api/signPOSTKý file PDF — body: { "file_url", "certificate_serial", "pin" } → trả về { "signed_file_base64" | "signed_file_url", "certificate_serial", "certificate_issuer", "plugin_version" }

Frontend gọi plugin qua http://127.0.0.1:{VGCA_USB_LOCAL_PORT}/api/... — port cấu hình trong SystemConfig (mặc định 31568). Timeout: 3s (health), 5s (certificates), 120s (sign).

D3. Luồng ký USB Token chi tiết

  1. Kiểm tra plugin: Frontend gọi /api/health. Nếu chưa chạy → hiển thị hướng dẫn tải & cài đặt plugin.
  2. Chọn chứng thư: Frontend gọi /api/certificates → hiển thị danh sách chứng thư → người ký chọn.
  3. Nhập PIN: Người ký nhập mã PIN USB Token.
  4. Kiểm tra chứng thư (OCSP/CRL): Frontend gọi checkCertificateStatus (backend) — xem Phần E. Nếu bị thu hồi/hết hạn → chặn ký.
  5. Ký file: Frontend gọi /api/sign → plugin tải file PDF từ file_url, ký bằng USB Token, trả về file đã ký.
  6. Upload file đã ký: Frontend upload file đã ký lên lưu trữ công khai (UploadPublicFile).
  7. Ghi nhận chữ ký: Frontend gọi usbTokenSign (backend) → tạo DigitalSignature + TSA + processSigningApproval.

D4. Cấu hình & bảo mật

PHẦN E — KIỂM TRA HIỆU LỰC CHỨNG THƯ (OCSP/CRL)

E1. Tổng quan

Trước khi ký (cả MPKI remote và USB Token), hệ thống kiểm tra chứng thư số chưa bị thu hồi và chưa hết hạn qua OCSP (Online Certificate Status Protocol — RFC 6960) hoặc CRL (Certificate Revocation List — RFC 5280). Yêu cầu theo Điều 28, Nghị định 130/2018/NĐ-CP.

E2. Backend function: checkCertificateStatus

FunctioncheckCertificateStatus
Input{ certificateSerial, certificateIssuer?, signatureId? }
Output{ status: 'good'|'revoked'|'expired'|'unknown', checked_at, raw_response, mock }
AuthNgười dùng đã đăng nhập

E3. OCSP (ưu tiên)

Endpoint{VGCA_OCSP_ENDPOINT}
MethodPOST
Content-Typeapplication/json
Body{ "serial": "...", "issuer": "..." }
Response{ "status": "good|revoked|expired|unknown" }

E4. CRL (fallback khi không có OCSP)

Endpoint{VGCA_CRL_ENDPOINT}
MethodGET
ResponseDanh sách chứng thư bị thu hồi (text/PEM/DER) — kiểm tra certificateSerial có trong danh sách không

E5. Mock mode

Khi chưa cấu hình OCSP/CRL endpoint → hệ thống tự chạy mock mode: giả định chứng thư hợp lệ (status='good'), cho phép test toàn bộ luồng UI. Khi admin điền endpoint vào SystemConfig → tự động chuyển sang production.

E6. Lưu trữ kết quả

Kết quả kiểm tra lưu vào DigitalSignature:

TrườngMô tả
certificate_statusgood / revoked / expired / unknown
certificate_checked_atThời điểm kiểm tra (ISO 8601)
ocsp_responsePhản hồi raw (JSON/text) — truy vết

PHẦN F — DẤU THỜI GIAN TIN CẬY (TSA — RFC 3161)

F1. Tổng quan

Sau khi ký thành công, hệ thống lấy dấu thời gian tin cậy (Timestamp Token) từ dịch vụ TSA của VGCA theo chuẩn RFC 3161. Đảm bảo tính pháp lý dài hạn — không phụ thuộc thời gian server nội bộ. Yêu cầu theo Điều 28, Nghị định 130/2018/NĐ-CP.

F2. Backend function: getTimestampToken

FunctiongetTimestampToken
Input{ fileHash, signatureId? }
Output{ tsp_token (base64), tsp_signed_at, mock }
AuthNgười dùng đã đăng nhập

F3. Gọi TSA endpoint

Endpoint{VGCA_TSA_ENDPOINT}
MethodPOST
Content-Typeapplication/timestamp-query
Body{ "hash": "...", "hashAlgorithm": "SHA-256" }
Response{ "token": "...", "timestamp": "..." } — Timestamp Token (RFC 3161)

F4. Mock mode

Khi chưa cấu hình TSA endpoint → hệ thống tự tạo mock timestamp token (base64 giả), cho phép test luồng. Khi admin điền endpoint → tự động chuyển sang production.

F5. Lưu trữ Timestamp Token

TrườngMô tả
tsp_tokenDấu thời gian tin cậy (base64) — Timestamp Token theo RFC 3161
tsp_signed_atThời điểm TSA cấp token (ISO 8601) — không phụ thuộc server nội bộ

F6. Tích hợp tự động

Function usbTokenSign tự động gọi getTimestampToken sau khi tạo DigitalSignature — không cần thao tác thủ công. Nếu TSA lỗi, chữ ký vẫn được ghi nhận (TSA là bổ sung pháp lý, không chặn flow ký).