Appearance
DRM Cryptographic Engine & Air-Gapped Licensing
1. Offline License Security Architecture
The Intelektika DRM system validates school lab server authenticity without requiring a permanent internet connection (Air-Gapped Validation). Issued license tokens bind cryptographically to the hardware identity (Hardware ID) of the school lab server.
mermaid
sequenceDiagram
autonumber
actor Proctor as School Proctor
participant Portal as Central Intelektika Portal
participant KeyStore as RSA-4096 Private Key
participant LabServer as School Lab CBT Server
Proctor->>Portal: Input NPSN, School Name, & Hardware ID
Portal->>KeyStore: Format canonical data string
KeyStore-->>Portal: RSA-SHA256 Digital Signature Bytes
Portal-->>Proktor: Base64 Token / License File (.lic)
Proctor->>LabServer: Import License Token
LabServer->>LabServer: Extract Payload & Verify Signature (RSA Public Key)
alt Valid Signature & Matching Hardware ID
LabServer-->>Proctor: License Verified & Active (Offline Mode)
else Invalid Signature / Hardware Mismatch
LabServer-->>Proctor: HTTP 403 / License Validation Failed
end2. Cryptographic Algorithm Specifications
- Key Type: RSA (Rivest-Shamir-Adleman) with 4096-bit key length.
- Signature Scheme: PKCS#1 v1.5 combined with SHA-256 cryptographic hash function.
- Canonical String Format Signed:text
licenseID + schoolName + hardwareID + expiresAt.Format(time.RFC3339)
3. Signed License JSON Payload Structure
Payload structure generated and signed by internal/pkg/drm/signer.go:
json
{
"license_id": "LIC-2026-0928-001",
"school_name": "SMA Negeri 1 Mojokerto",
"max_students": 500,
"hardware_id": "CPU-UUID-9988-7766-5544",
"operating_mode": "SEMI_OFFLINE",
"sync_url": "https://[DOMAIN_DOKUMENTASI]/api/v1/sync",
"sync_url_locked": true,
"issued_at": "2026-09-28T00:00:00Z",
"expires_at": "2027-09-28T23:59:59Z",
"signature": "Base64EncodedRSASignatureBytes=="
}4. Go Implementation Code (internal/pkg/drm/signer.go)
go
func SignLicense(
privKey *rsa.PrivateKey,
licenseID, schoolName, hardwareID, operatingMode, syncURL string,
syncURLLocked bool, maxStudents int, expiresAt time.Time,
) (string, *LicensePayload, error) {
if privKey == nil {
return "", nil, errors.New("private key cannot be nil")
}
issuedAt := time.Now().UTC()
expiresAt = expiresAt.UTC()
// Format canonical data string
dataToSign := licenseID + schoolName + hardwareID + expiresAt.Format(time.RFC3339)
hashed := sha256.Sum256([]byte(dataToSign))
// Sign hash using RSA PKCS#1 v1.5 + SHA-256
sigBytes, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hashed[:])
if err != nil {
return "", nil, fmt.Errorf("failed to sign license payload: %w", err)
}
payload := &LicensePayload{
LicenseID: licenseID,
SchoolName: schoolName,
MaxStudents: maxStudents,
HardwareID: hardwareID,
OperatingMode: operatingMode,
SyncURL: syncURL,
SyncURLLocked: syncURLLocked,
IssuedAt: issuedAt,
ExpiresAt: expiresAt,
Signature: base64.StdEncoding.EncodeToString(sigBytes),
}
jsonBytes, err := json.Marshal(payload)
if err != nil {
return "", nil, fmt.Errorf("failed to marshal payload: %w", err)
}
rawKey := base64.StdEncoding.EncodeToString(jsonBytes)
return rawKey, payload, nil
}