Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/patriksvensson/license-key
A library for generating and verifying license keys.
https://github.com/patriksvensson/license-key
license license-checker license-checking software-license software-licensing
Last synced: about 2 months ago
JSON representation
A library for generating and verifying license keys.
- Host: GitHub
- URL: https://github.com/patriksvensson/license-key
- Owner: patriksvensson
- License: mit
- Created: 2020-07-13T21:02:48.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2020-07-13T21:37:24.000Z (over 4 years ago)
- Last Synced: 2024-10-19T18:01:42.360Z (2 months ago)
- Topics: license, license-checker, license-checking, software-license, software-licensing
- Language: Rust
- Homepage: https://crates.io/crates/license-key
- Size: 7.81 KB
- Stars: 59
- Watchers: 2
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# license-key
A library for generating and verifying license keys without requiring
an Internet connection. For further protection, you can of course
validate the license key over the Internet.# Features
* Does not require an Internet connection.
* Easy to revoke specific license keys in a software update.
* Not possible to disassemble an application to gain
insight into how to generate a 100% working key since
the verification process doesn't check the whole license key.For more information, read
[Implementing a Partial Serial Number Verification System in Delphi](https://www.brandonstaggs.com/2007/07/26/implementing-a-partial-serial-number-verification-system-in-delphi)
which this crate was based upon.# Anatomy of a license key
Every license key consists of a seed, a payload and a checksum.
Each byte in the payload is an operation of the seed and an
initialization vector. The 16-bit checksum is there to quickly check if
the key is valid at all, while the seed is a 64-bit hash of something
that identifies the license key owner such as an e-mail address or similar.The size of the payload depends on how big the initialization vector is.
In the example below, we are using a 5-byte intitialization vector which
results in a 5-byte payload.```text
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│0x0│0x1│0x2│0x3│0x4│0x5│0x6│0x7│0x8│0x9│0xa│0xb│0xc│0xd│0xe│0xf│
├───┴───┴───┴───┴───┴───┴───┴───┴───┼───┴───┴───┴───┴───┼───┴───┤
│ SEED │ PAYLOAD │ CHECK │
│ │ │ SUM │
└───────────────────────────────────┴───────────────────┴───────┘
```# Generating a license key
```rust
use license_key::*;// Define a hasher that will hash the seed and a initialization vector.
// DON'T USE THIS ONE. It's only for demonstrational purposes.
struct DummyHasher { }
impl KeyHasher for DummyHasher {
fn hash(&self, seed: u64, a: u64, b: u64, c: u64) -> u8 {
((seed ^ a ^ b ^ c) & 0xFF) as u8
}
}// Create a license generator
// We use only four triplets in our initialization vector,
// but in a real world scenario you would want to use a lot more.
let generator = Generator::new(
DummyHasher { },
vec![
// DON'T USE THIS ONE.
// Generate your own.
(114, 83, 170),
(60, 208, 27),
(69, 14, 202),
(61, 232, 54)
],
);// Generate a license key using a seed.
// A seed is unique per license key, and could be a hash of an e-mail address or similar.
// You can later block individual seeds during verification.
let key = generator.generate(1234567891011121314_u64);// Write the key in hex format to the console.
// This will output something like: 112210F4B2D230A229552341B2E723
println!("{}", key.serialize::());
```# Verifying a license key
```rust
use license_key::*;// Use the exact same hasher that we used when generating the key
struct DummyHasher { }
impl KeyHasher for DummyHasher {
fn hash(&self, seed: u64, a: u64, b: u64, c: u64) -> u8 {
((seed ^ a ^ b ^ c) & 0xFF) as u8
}
}// Create the license key verifier
let mut verifier = Verifier::new(
DummyHasher { },
vec![
// Use the first byte (zero indexed) from the initialization vector.
// If a third-party key generator is created for the app, simply change this
// to another byte and any forged keys won't work anymore.
ByteCheck::new(0, (114, 83, 170)),
],
);// Block a specific seed.
// You might want to do this if a key was leaked or the the
// license key owner requested a refund.
verifier.block(11111111_u64);// Parse a key in hex format
let key = LicenseKey::parse::("112210F4B2D230A229552341E723");// Verify the license key
match verifier.verify(&key) {
Status::Valid => println!("Key is valid!"),
Status::Invalid => println!("Key is invalid!"),
Status::Blocked => println!("Key has been blocked!"),
Status::Forged => println!("Key has been forged!"),
}
```