批量生產設備,每台設備唯一機器碼。使用者購買充值卡(帳號/密碼/授權碼),輸入後驗證通過解鎖功能。**設備完全離線**,無法連網驗證。
離線環境下,**所有驗證邏輯在客戶端**,攻擊者可反編譯、Hook、修改二進制繞過檢查。無法做到絕對安全,只能**提高破解成本**。
// 輸入:機器碼、授權類型、有效期、功能位圖
// 輸出:授權碼 (Base64)
String payload = machineCode + "|" + featureBitmap + "|" + expiryTimestamp + "|" + nonce;
byte[] signature = RSA_SIGN(privateKey, payload.getBytes(StandardCharsets.UTF_8));
String authCode = Base64.encode(payload + "." + signature);
public boolean verifyLicense(String authCode, String machineCode) {
try {
String[] parts = authCode.split("\\.");
if (parts.length != 2) return false;
String payload = new String(Base64.decode(parts[0]));
byte[] signature = Base64.decode(parts[1]);
// 1. 驗證簽名
if (!RSA_VERIFY(publicKey, payload.getBytes(), signature)) return false;
// 2. 解析 payload
String[] fields = payload.split("\\|");
if (fields.length < 4) return false;
String licensedMachine = fields[0];
long expiry = Long.parseLong(fields[2]);
// 3. 機器碼綁定檢查
if (!machineCode.equals(licensedMachine)) return false;
// 4. 有效期檢查 (需可信時間源,見下文)
if (System.currentTimeMillis() > expiry) return false;
// 5. 解析功能位圖,啟用對應功能
int features = Integer.parseInt(fields[1]);
enableFeatures(features);
return true;
} catch (Exception e) {
return false;
}
}
| 方案 | 原理 | 繞過難度 |
|---|---|---|
| RTC 硬體時鐘 | 讀取主板電池供電的 RTC | 中 (可修改 BIOS/硬體) |
| 單調時間 + 重啟檢測 | SystemClock.elapsedRealtime() + 記錄上次時間,檢測時間倒退 | 中高 (需 Root 修改內核) |
| 安全元件 (SE/TEE) | 硬體隔離的可信時間 | 極高 (需硬體支援) |
| 無時間限制 (永久授權) | 僅驗證機器碼與功能 | 最簡單,無時間攻擊面 |