Giao thức CLV1 đã công khaiĐọc đặc tả
Mục lục thư viện

Thư viện tài liệuBản quyền

Thiết bị, HWID và chuyển máy

Mỗi license key chỉ chạy trên một số máy nhất định. Hướng dẫn này giải thích cách ClavisAUH nhận ra một máy, chuyện gì xảy ra khi key đã đủ máy, cách khách đổi máy theo luật bạn đặt, và cách bạn theo dõi, chặn hay kết thúc phiên đăng nhập từ dashboard.

9 phút đọc

Cách một máy được nhận diện

Mỗi lần kích hoạt hoặc đăng nhập, phần mềm gửi kèm mô tả thiết bị:

  • fingerprint: một hash ổn định đại diện cho cả máy (HWID).
  • components: các thành phần phần cứng đã hash, mỗi thành phần có một tên riêng như cpu, disk, board.
  • name, platform: tên máy và hệ điều hành, dùng để hiển thị trong dashboard.
  • Phiên bản đang chạy và hash bản build, nếu bạn khai báo appVersion, buildHash trong SDK.

Giá trị phần cứng gốc không bao giờ rời khỏi máy. SDK JavaScript có hàm hashComponent: cắt khoảng trắng, chuyển chữ thường, băm SHA-256 rồi lấy 32 ký tự hex đầu. Server chỉ so hash với hash.

import { ClavisClient, ClavisError, hashComponent } from "@clavisauh/sdk";

const clavis = new ClavisClient({
  baseUrl: "https://api.example.com",
  appId: "app_…",
  appPublicKey: "…",
  device: {
    // machineId, cpuId… là giá trị thô do phần mềm của bạn tự đọc
    fingerprint: hashComponent(machineId),
    components: {
      cpu: hashComponent(cpuId),
      disk: hashComponent(diskSerial),
      board: hashComponent(boardSerial),
      mac: hashComponent(primaryMac),
    },
    name: hostName,
    platform: "windows",
  },
  // Lưu khoá thiết bị trong keychain của hệ điều hành để máy giữ danh tính
  deviceKey: await loadDeviceKey(),
});

Ngoài HWID, mỗi máy còn có một khoá thiết bị (cặp khoá Ed25519) ký mọi yêu cầu. Phiên đăng nhập gắn với khoá này, nên mã phiên bị lộ cũng vô dụng ở máy khác. Hãy lưu deviceKey bền vững thay vì tạo mới mỗi lần mở phần mềm.

Cùng một máy sau khi cài lại hoặc thay linh kiện

Khi một máy kích hoạt key, server so nó với các máy đang giữ suất của key theo thứ tự:

  1. Trùng fingerprint: đúng máy cũ.
  2. Không trùng fingerprint nhưng có ít nhất N thành phần cùng tên và cùng hash: vẫn là máy cũ. N là fingerprintThreshold của gói, mặc định 3 (hợp lệ từ 1 đến 8). Form gói trong dashboard hiện chưa có ô chỉnh giá trị này.

Nếu là máy cũ, server dùng lại đúng suất đó và cập nhật thông tin mới (fingerprint, thành phần, IP, phiên bản). Cài lại hệ điều hành hay thay một ổ đĩa không làm tốn thêm suất.

Giới hạn thiết bị mỗi key

Số máy của một key lấy từ ô Số máy của gói, hoặc từ ô Số thiết bị mỗi key khi bạn tạo key trong Phát hành & bản quyền › License. Con số được ghi vào từng key lúc tạo: sửa gói sau đó không đổi số máy của các key đã phát hành. Gói workspace đặt mức trần Thiết bị mỗi key, xem tại Tài khoản & tổ chức › Gói & sử dụng.

Việc đếm máy chạy trong một transaction khoá dòng license, nên nhiều máy kích hoạt cùng lúc cũng không vượt giới hạn. Máy đang ngủ (xem bên dưới) không chiếm suất.

Khi key đã đủ máy

Máy vượt giới hạn bị từ chối với mã device_limit (HTTP 403). Lần từ chối được ghi vào nhật ký hoạt động và tính là tín hiệu Chia sẻ key trong Protect 24/7.

try {
  await clavis.activate(licenseKey);
} catch (err) {
  if (err instanceof ClavisError && err.code === "device_limit") {
    // Báo khách: key đã dùng đủ số máy, hãy trả suất một máy cũ hoặc liên hệ người bán
  }
}

Xem máy bị từ chối và cho nó vào

Khi khách báo "đổi máy mới không vào được", bạn không cần đoán:

  1. Mở Phát hành & bản quyền › License, bấm vào dòng key (hoặc chọn Xem chi tiết trong menu của dòng).
  2. Ở mục Thiết bị, dưới máy giống máy bị từ chối nhất, có dòng "Máy … bị từ chối, so với máy này" kèm danh sách thành phần: dấu tích là trùng, dấu chéo là khác. Chỉ có tên thành phần, không số serial nào hiện ra.
  3. Nếu đúng là khách thay máy, bấm Cho phép máy này. Suất của máy cũ được trả lại và máy mới vào được ở lần kích hoạt kế tiếp.

Thao tác này được ghi vào Lịch sử chuyển máy là "Người bán gỡ" và không trừ vào lượt chuyển máy của khách.

Máy đang ngủ và tự trả suất

Máy không đăng nhập và không gửi heartbeat trong một khoảng thời gian sẽ tự trả suất, để khách không bị kẹt vì một máy đã hỏng hay đã bán.

  • Thời gian chờ đặt ở ô Máy im lặng thì trả suất (giờ) của gói. Để trống là 72 giờ, 0 là không bao giờ.
  • Một tác vụ nền chạy khoảng 15 phút một lần và chuyển các máy quá hạn sang trạng thái ngủ. Trong ngăn chi tiết license, máy ngủ có biểu tượng mặt trăng và dòng Đang ngủ, đã trả suất.
  • Trong 7 ngày kể từ lúc ngủ, nếu chính máy đó quay lại (nhận ra bằng fingerprint hoặc thành phần), nó lấy lại một suất trống và không tính là một lần chuyển máy. Nếu key đã đủ máy trong lúc đó, nó nhận device_limit như mọi máy khác.
  • Ngủ quá 7 ngày, máy bị gỡ hẳn. Lần sau quay lại, nó cần một suất trống như một máy mới.

Luật chuyển máy

Chuyển máy là trả suất của một máy để máy khác dùng. Luật nằm trong phần Chuyển máy của gói, tại Phát hành & bản quyền › Đăng nhập & gói license (bấm vào một gói hoặc Thêm gói):

ÔÝ nghĩa
Lần mỗi 30 ngàySố lần khách được tự chuyển trong 30 ngày gần nhất
Chờ giữa hai lần (giờ)Khoảng cách tối thiểu giữa hai lần khách chuyển
Người bán, Khách, Đại lýAi được chuyển máy

Các ô này chính là phương pháp Quy định chuyển máy, và có hiệu lực ở cả hai chế độ bảo vệ. Ô số để trống thì dùng mặc định: 2 lần mỗi 30 ngày, cách nhau 24 giờ.

Ai chuyển được, và bằng cách nào:

  • Bạn (người bán): gỡ một máy bằng nút X Trả suất cho máy này trong ngăn chi tiết license, hoặc qua Seller API. Không bao giờ bị giới hạn, chỉ được ghi vào lịch sử. Muốn gỡ mọi máy của key cùng lúc, chọn Đặt lại thiết bị trong menu của dòng; mọi phiên của key cũng kết thúc.
  • Khách: khi gói tick Khách, khách tự trả suất từ phần mềm bằng clavis.transfer() hoặc bằng nút Gỡ máy trong cổng khách hàng. Hai đường này dùng chung lượt và thời gian chờ.
  • Đại lý: khi gói tick Đại lý, đại lý đặt lại thiết bị cho key họ đã bán qua Reseller API. Nếu không, họ nhận transfer_not_allowed.
try {
  const { remaining } = await clavis.transfer();
  // Máy này đã trả suất; remaining là số lượt chuyển còn lại trong 30 ngày
} catch (err) {
  if (err instanceof ClavisError && err.code === "transfer_limited") {
    // Hết lượt hoặc chưa hết thời gian chờ: err.message có thời điểm thử lại
  }
}

transfer() cần một phiên đang sống, nên hãy gọi trước khi khách rời máy cũ. Khi bị từ chối, server trả HTTP 429 với transfer_limited (hết lượt hoặc đang chờ) hoặc transfer_not_allowed (gói không cho khách chuyển). Dòng Chuyển máy trong ngăn chi tiết license cho biết khách đã dùng bao nhiêu lượt. Mỗi lần khách tự chuyển phát sự kiện webhook device.transferred; máy mới gắn vào key phát device.added.

Chặn một máy trong toàn app

Máy bị chặn không vào được app này với bất kỳ key nào, vì server so fingerprint của nó với mọi máy bị chặn trong app. Mọi phiên đang chạy trên máy đó kết thúc ngay, và mỗi lần đăng nhập lại nhận device_blocked. Đây là phương pháp Denylist thiết bị, và lệnh chặn có hiệu lực ở cả hai chế độ bảo vệ.

Có bốn cách chặn:

  1. Mở Người dùng cuối › Thiết bị & phiên, tab Thiết bị, bấm Chặn cạnh máy đó và nhập lý do.
  2. Mở Bảo mật ứng dụng › Bảo vệ. Trong danh sách Cần xử lý, với chủ thể là thiết bị, bấm Chặn máy và nhập lý do. Ngăn chi tiết sự cố của một thiết bị cũng có nút này.
  3. Qua Seller API: POST /devices/{id}/actions với {"action": "block"}, cần quyền devices:write.
  4. Tự động: Xử lý theo mức rủi ro ở chế độ Tự xử lý (chạy trên Premium) chặn máy khi tín hiệu Chia sẻ key hoặc Bản build lạ lặp lại.

Bỏ chặn bằng nút Bỏ chặn cạnh máy ở tab Thiết bị, trong ngăn chi tiết license hoặc trong ngăn sự cố, hay Hoàn tác hành động trong lịch sử sự cố.

Phiên đăng nhập

Mỗi lần đăng nhập thành công tạo một phiên gắn với máy và khoá thiết bị. Phiên sống 1 giờ nếu không có heartbeat; khi bật Session lease ngắn hạn, phiên sống gấp ba khoảng Nhịp báo. Mỗi lần gọi heartbeat() gia hạn phiên.

Trang Thiết bị & phiên

Người dùng cuối › Thiết bị & phiên có hai tab. Phiên cho thấy phần mềm đang đăng nhập ngay lúc này và tự làm mới mỗi 15 giây: thiết bị, license, người dùng, vị trí (quốc gia và IP), lần cuối thấy. Thiết bị liệt kê mọi thiết bị đang gắn với key của app này, dù đang đăng nhập hay không, kèm license, IP gần nhất và lần cuối thấy.

Ở tab Phiên, bấm X (Kết thúc phiên) ở cuối dòng để kết thúc một phiên. Lần gọi kế tiếp của phần mềm nhận session_expired và phải đăng nhập lại. Kết thúc phiên không gỡ máy khỏi key: muốn lấy lại suất thì trả suất trong ngăn chi tiết license, muốn giữ máy ở ngoài thì chặn máy.

Kết thúc nhiều phiên cùng lúc

Trang này chưa có nút kết thúc mọi phiên của app. Các cách hiện có:

  • Cả app: Seller API POST /apps/{appId}/sessions/revoke-all (quyền sessions:write), trả về số phiên đã kết thúc.
  • Một key: Tạm khoá kết thúc mọi phiên của key; Đặt lại thiết bị kết thúc mọi phiên và gỡ mọi máy.
  • Một người dùng: Cấm hoặc Đặt lại mật khẩu trong Người dùng cuối › Người dùng kết thúc mọi phiên của người đó.

Giới hạn session đồng thời

Số máy giới hạn nơi key được cài; số phiên đồng thời giới hạn nơi key chạy cùng lúc. Ví dụ key 3 máy với 1 phiên: khách cài ở nhà và ở công ty, nhưng mỗi lúc chỉ mở được ở một nơi.

  • Ô Phiên cùng lúc của gói đặt giới hạn này, ở cả hai chế độ bảo vệ. Để trống thì không giới hạn.
  • Đăng nhập lại trên cùng một máy thay phiên cũ của máy đó, không bị tính thêm.
  • Khi số phiên còn sống trên các máy khác đã chạm giới hạn, lần đăng nhập mới nhận session_limit và Protect ghi tín hiệu Vượt phiên đồng thời.

Mã lỗi thường gặp

MãHTTPKhi nào
device_limit403Key đã đủ máy
device_blocked403Máy bị chặn trong app
device_revoked403Máy đã bị gỡ khỏi license
session_limit403Vượt số phiên đồng thời
session_expired401Phiên đã kết thúc hoặc hết hạn, cần đăng nhập lại
transfer_limited429Hết lượt chuyển hoặc đang trong thời gian chờ
transfer_not_allowed429 (403 với đại lý)Gói không cho phép người này chuyển máy

Mọi lần từ chối khi đăng nhập đều nằm trong Bảo mật ứng dụng › Nhật ký hoạt động kèm mã lý do. Danh sách đầy đủ có trong tham chiếu giao thức.

Liên quan

Bạn cần giúp gì?

Câu hỏi thường gặp

ClavisAUH là gì?

Dịch vụ bản quyền và xác thực cho phần mềm desktop: license key, khoá thiết bị, đăng nhập người dùng và phản hồi có chữ ký. Tất cả quản lý trên một dashboard

Vì sao kẻ crack không làm giả được server?

SDK chỉ tin câu trả lời ký bằng khoá bí mật của ứng dụng. Khoá đó không bao giờ rời server của chúng tôi, nên server giả không ký được và bị từ chối

Trong file chạy của tôi có gì?

Mã ứng dụng và khoá công khai. Không có bí mật nào, vì mỗi thiết bị tự tạo cặp khoá riêng ở lần chạy đầu

Có chạy được khi offline không?

Có. Mọi gói đều có token offline có chữ ký dùng được 7 ngày, ứng dụng tự kiểm tra tại máy. Premium cho bạn chọn bao lâu. License đã thu hồi vẫn có thể chạy offline trong khoảng đó, trừ khi Chế độ chỉ online đang bật

Hỗ trợ những ngôn ngữ nào?

Hiện có JavaScript và TypeScript. Tiếp theo là C++, C# và Python, cùng một giao thức công khai

Gói Basic có miễn phí thật không?

Có. Không giới hạn thời gian, không cần thẻ. Cần nhiều hơn thì lên Premium

Liên hệ