# ๐ 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`:
```toml
[dependencies]
offline-license-validator = "0.1.0"
```
## ๐ Quick Start
```rust
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
```rust
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
```rust
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
```rust
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:
| **Linux/macOS** | `~/.offline-license/license.json` |
| **Windows** | `%USERPROFILE%\.offline-license\license.json` |
## ๐ ๏ธ API Reference
### `LicenseValidator`
```rust
// 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
```rust
// 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
```rust
pub enum LicenseError {
InvalidFormat(String),
InvalidEncoding(base64::DecodeError),
InvalidSignature,
InvalidJson(serde_json::Error),
HwidMismatch { expected: String, actual: String },
Expired(DateTime<Utc>),
InvalidPublicKey(String),
}
```
## ๐งช Testing
```bash
cargo test
```
## ๐ License Format
Licenses use the format: `Base64(JSON_Payload).Base64(Ed25519_Signature)`
Example payload:
```json
{
"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](https://krakiun.com)** - Expert Software Development & Security Solutions
Built with:
- [`ed25519-dalek`](https://crates.io/crates/ed25519-dalek) - Ed25519 signatures
- [`base64`](https://crates.io/crates/base64) - Base64 encoding
- [`chrono`](https://crates.io/crates/chrono) - Date/time handling
- [`serde`](https://crates.io/crates/serde) - Serialization
---
**Need custom licensing solutions or security consulting?** Visit [krakiun.com](https://krakiun.com)