offline-license-validator 0.1.1

Offline license validation library using Ed25519 signatures
Documentation

๐Ÿ” Offline License Validator

A simple, secure Rust library for offline license validation using Ed25519 signatures.

โœจ Features

  • โœ… Ed25519 Cryptography - Industry-standard digital signatures
  • โœ… HWID Binding - Licenses tied to specific hardware
  • โœ… Expiration Checking - Automatic validation
  • โœ… Persistent Storage - Saves to ~/.offline-license/
  • โœ… Zero Dependencies on Runtime - Pure Rust, no network required
  • โœ… Easy Integration - Just 3 lines of code

๐Ÿ“ฆ Installation

Add to your Cargo.toml:

[dependencies]
offline-license-validator = "0.1.0"

๐Ÿš€ Quick Start

use offline_license_validator::{LicenseValidator, storage};

// 1. Initialize with your public key (from admin app)
let validator = LicenseValidator::new(
    "913d5e19269699e51bcdb5c5a7106c278ef0e0fe92d31b76b6daf5bb00594fcf"
).expect("Invalid public key");

// 2. Validate license
match validator.validate(license_string, hardware_id) {
    Ok(info) => {
        println!("โœ“ License valid until: {}", info.expires_at);

        // 3. Save for offline use
        storage::save_license(&info, license_string).ok();
    }
    Err(e) => eprintln!("โœ— License invalid: {}", e),
}

๐Ÿ“– Usage Examples

Basic Validation

use offline_license_validator::LicenseValidator;

const PUBLIC_KEY: &str = "your_public_key_hex_here";

fn main() {
    let validator = LicenseValidator::new(PUBLIC_KEY).unwrap();

    let license = "eyJod2lkIjoiYWJjMTIzLi4uIiwi...";
    let hwid = "8b83180aa8f4ed018cb2991e0ff7e9b4...";

    match validator.validate(license, hwid) {
        Ok(info) => {
            println!("License Type: {}", info.license_type);
            println!("Expires: {}", info.expires_at);
        }
        Err(e) => eprintln!("Error: {}", e),
    }
}

With Persistent Storage

use offline_license_validator::{LicenseValidator, storage};

fn verify_and_save(license: &str, hwid: &str) -> Result<(), Box<dyn std::error::Error>> {
    let validator = LicenseValidator::new(PUBLIC_KEY)?;
    let info = validator.validate(license, hwid)?;

    // Save to ~/.offline-license/license.json
    storage::save_license(&info, license)?;

    println!("License saved successfully!");
    Ok(())
}

fn load_cached_license() -> Option<String> {
    storage::load_saved_license()
        .ok()?
        .map(|(license_string, _)| license_string)
}

Tauri Integration

use offline_license_validator::{LicenseValidator, storage};

const PUBLIC_KEY: &str = "913d5e19269699e51bcdb5c5a7106c278ef0e0fe92d31b76b6daf5bb00594fcf";

#[tauri::command]
fn verify_license(license: String, hwid: String) -> Result<String, String> {
    let validator = LicenseValidator::new(PUBLIC_KEY)
        .map_err(|e| e.to_string())?;

    let info = validator.validate(&license, &hwid)
        .map_err(|e| e.to_string())?;

    // Save validated license
    storage::save_license(&info, &license)
        .map_err(|e| e.to_string())?;

    Ok(format!("Valid until: {}", info.expires_at))
}

#[tauri::command]
fn get_cached_license() -> Result<Option<String>, String> {
    storage::load_saved_license()
        .map(|opt| opt.map(|(s, _)| s))
        .map_err(|e| e.to_string())
}

๐Ÿ”’ Security

  • Public key is hardcoded in your application (safe)
  • Ed25519 signatures prevent tampering (64-byte signatures)
  • HWID binding prevents license sharing across devices
  • No network required for validation (fully offline)
  • Expiration checks prevent use after expiry date

๐Ÿ“ Storage Location

Validated licenses are saved to:

Platform Path
Linux/macOS ~/.offline-license/license.json
Windows %USERPROFILE%\.offline-license\license.json

๐Ÿ› ๏ธ API Reference

LicenseValidator

// Create new validator
LicenseValidator::new(public_key_hex: &str) -> Result<Self, LicenseError>

// Validate license
validate(&self, license_string: &str, hwid: &str) -> Result<ValidLicenseInfo, LicenseError>

storage module

// Save validated license
save_license(info: &ValidLicenseInfo, license_string: &str) -> Result<(), std::io::Error>

// Load saved license
load_saved_license() -> Result<Option<(String, ValidLicenseInfo)>, std::io::Error>

// Delete saved license
delete_saved_license() -> Result<(), std::io::Error>

Error Types

pub enum LicenseError {
    InvalidFormat(String),
    InvalidEncoding(base64::DecodeError),
    InvalidSignature,
    InvalidJson(serde_json::Error),
    HwidMismatch { expected: String, actual: String },
    Expired(DateTime<Utc>),
    InvalidPublicKey(String),
}

๐Ÿงช Testing

cargo test

๐Ÿ“ License Format

Licenses use the format: Base64(JSON_Payload).Base64(Ed25519_Signature)

Example payload:

{
  "hwid": "8b83180aa8f4ed018cb2991e0ff7e9b4...",
  "issued_at": "2026-03-12T14:17:53Z",
  "expires_at": "2027-03-09T23:59:59Z",
  "license_type": "PRO",
  "metadata": null
}

๐Ÿค Integration Workflow

  1. Admin App generates Ed25519 keypair
  2. Admin App creates signed license for specific HWID
  3. Your App hardcodes public key
  4. Your App validates license using this library
  5. Library saves validated license to ~/.offline-license/

๐Ÿ“„ License

MIT License - See LICENSE file for details

๐Ÿ™ Credits

Developed by Krakiun - Expert Software Development & Security Solutions

Built with:


Need custom licensing solutions or security consulting? Visit krakiun.com