5 stable releases
Uses old Rust 2015
2.1.0 | Feb 10, 2018 |
---|---|
2.0.0 | Feb 2, 2018 |
1.3.0 | Jan 31, 2018 |
1.2.1 | Jan 15, 2018 |
1.1.0 | Aug 15, 2017 |
#1033 in Cryptography
2MB
324 lines
Contains (Mach-o exe, 2MB) builds/osx/v1.3/keygen, (Mach-o exe, 2MB) builds/osx/v1.0/keygen, (Mach-o exe, 2MB) builds/osx/v1.1/keygen
Keygen
Creates a serial key from a seed, based on this article.
The serial key can be checked for validity, either by using a checksum or by verifying bytes in the key.
Installation
Cargo
cargo install keygen
Other
Windows/Linux: Compile from source using Rust - no binaries at the mo.
Mac: v1.1
Usage
keygen create
Creates a key from an initial string value.
-s --seed REQUIRED
Initial value to use to create the string
keygen create -s myname@example.com
-h --hash
String to combine with the seed when creating the key. If you don't provide a hash, a random one will be generated and used.
keygen create -s myname@example.com -h aLongstringValueasaHash
-c -- config
Path to existing JSON config file. This file will be read when creating the key.
keygen create -s myname@example.com -c config.json
-b -- blacklist MULTIPLE
Seed values to add to a blacklist. Any keys with seed values in the blacklist will fail verification.
// key = 53A5-4C20-A43E-6490-052A
keygen create -s myname@examplecom -b 11111111 -b 53A54C20
keygen verify -k 53A5-4C20-A43E-6490-052A -c config.json // => Blacklisted
-l --length
Number of bytes to create in the key. Longer keys should be tricker to crack but are more difficult for users to type. Keys are made up of the seed (8 characters long), a length of bytes (2 characters per byte), then the checksum (4 characters).
keygen create -s myname@example.com -l 12 // => 53A5-4C20-7474-CC94-AF39-B63D-8B34-54A7-C1DA
keygen create -s myname@example.com -l 4 // => 53A5-4C20-A43E-6490-052A
-y --shifts
OPTIONAL Byte shifts to use when creating a key. If not provided, then these will be generated. Must be triplets of i16 ie 12,242,45 16,80,52
keygen create -y 74,252,42 178,245,197 1,201,98
-o --output
Path to which to write config settings. When creating a key it's vital to save the config used to create the key, otherwise you won't be able to verify it. If you provide an output value, then a file with the value's name will be created and the config will be saved there as JSON. If this value isn't provided, JSON config will be printed out to the terminal.
keygen create -s myname@example.com -o config.json
-j --json
Flag: if present, output will be written to stdout as JSON data. A config file will not be created/written if this flag is set.
keygen create -s myname@example.com -l 8 -h abc123 -j
// =>
{"config":{"blacklist":[],"byte_shifts":[[98,133,163],[26,206,205],[244,140,88],[149,39,147],[208,215,29],[161,77,140],[178,216,229],[216,29,79]],"hash":"Cc7MgAsUr43PyT4U2zW5dDkVIKK23hB","num_bytes":8},"key":"92E7-A4A6-265A-5425-99FC-3088-C404"}
keygen verify
Check that a key is valid. Returns Keygen::Status
.
keygen verify -k 1234-5678-abcd-1234 -c config.json // => Status::Good, Status::Invalid, Status::Blacklisted, Status::Phony
-k --key REQUIRED
Key to check.
-c --config REQUIRED
(unless shifts and positions are passed)
Path to JSON config file; must be the config used to create the key.
-s --shifts REQUIRED
(unless config provided)
Byte shifts used when generating the key, triplets of i16. These must match the position params ie if position is [0, 1] then you must pass the first two byte shifts which were used when creating the key.
-p --positions
(REQUIRED if shifts provided)
Bytes to check in the key
ie with a key of 1234-5678-abcd-1234, positions of [0, 1] would check the first two bytes in the key (ab
and cd
- 1234-5678
is the seed value).
keygen verify -k 1234-5678-abcd-1234 -s 74,252,42 42,116,226 -p 0 1
keygen checksum
Check that a key's checksum is correct (ie that the key hasn't been altered). Returns bool
.
Requires either the expected length of the key or a path to a config file (where it reads the expected length).
keygen checksum -k 1234-5678-abcd-1234 -c config.json // => true
keygen checksum -k 1234-5678-abcd-1234 -l 2 // => true
-k --key REQUIRED
Key to check.
-l --length REQUIRED
(required unless config argument provided)
Expected length of key to check.
-c --config REQUIRED
(required unless length argument provided)
Path to JSON config file; must be the config used to create the key.
Seeds
Seeds are created from the input and hash being run through CRC32
- they are always eight characters long in hexadecimal format.
Config
The config is vital once a key has been created - if you don't save the config, or try to use a different one to verify a key, you won't be able to validate keys! The config file contains information which can be used to generate keys, so needs to be kept secret. You can use the same config to generate multiple keys by using the -c
argument when creating a key.
Example configuration
"num_bytes": 8, // length of key
"byte_shifts": [ // array of arrays - these are used to check each byte
[62, 252, 46],
[57, 195, 131],
[21, 251, 32],
[129, 94, 254],
[205, 24, 45],
[161, 36, 17],
[88, 109, 26],
[105, 237, 248]
],
"hash": "hash", // the hash used in creating the string
"blacklist": ["11111111"] // blacklisted seeds
}
Verification/Checksum
The keygen checksum
method is a quick and fairly inaccurate way to determine whether a key is invalid or not - it only checks whether the checksum matches the rest of the key, although it is possible to alter the key and checksum and still end up valid. The verify function checks the checksum along with several bytes in the key to determine if the key actually is valid - the full reasoning is in the original article, but essentially this is so you have a quick-and-dirty way to check the key's valid on startup (checksum
), and a full check later when trying to use more funcationlity like saving. Having the quick check on startup means reverse-engineers don't know exactly when the full check happens in the software so there isn't an obvious entry point.
Dependencies
~7MB
~137K SLoC