Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rollerworks/split-token
Split Tokens: Token-Based Authentication Protocol without Side-Channels
https://github.com/rollerworks/split-token
authentication crypto php rollerworks security sodium split-token token
Last synced: 11 days ago
JSON representation
Split Tokens: Token-Based Authentication Protocol without Side-Channels
- Host: GitHub
- URL: https://github.com/rollerworks/split-token
- Owner: rollerworks
- License: mpl-2.0
- Created: 2019-01-15T18:01:29.000Z (almost 6 years ago)
- Default Branch: main
- Last Pushed: 2024-01-06T13:02:16.000Z (11 months ago)
- Last Synced: 2024-10-11T21:21:08.579Z (about 1 month ago)
- Topics: authentication, crypto, php, rollerworks, security, sodium, split-token, token
- Language: PHP
- Size: 62.5 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
Rollerworks SplitToken Component
================================SplitToken provides a Token-Based Authentication Protocol without Side-Channels.
This technique is based of [Split Tokens: Token-Based Authentication Protocols without Side-Channels].
Which was first proposed by Paragon Initiative Enterprises.SplitToken-Based Authentication is best used for password resetting or one-time
single-logon.While possible, this technique is not recommended as a replacement for
OAuth or Json Web Tokens.## Introduction
Unlike _traditional_ Token-Based Authentication Protocols a SplitToken consists
of two parts: The **selector** (used in the query) and the **verifier**
(not used in the query).* The selector is a 24 bytes fixed-length random string, which used as an identifier.
You can safely create an unique index for field.* The verifier works as a password and is only provided to the user,
the database only holds a salted (cryptographic) hash of the verifier.The length of this value is heavily dependent on the used hashing algorithm
and should not be hardcoded.The full token is provided to the user or recipient and functions as a combined
identifier (selector) and password (verifier).**Caution: You NEVER store the full token as-is!** You only store the selector,
and a (cryptographic) hash of the verifier.## Installation
To install this package, add `rollerworks/split-token` to your composer.json:
```bash
$ php composer.phar require rollerworks/split-token
```Now, [Composer][composer] will automatically download all required files,
and install them for you.## Requirements
PHP 8.1 with the sodium extension enabled (default since PHP 8).
## Basic Usage
```php
\PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
'time_cost' => \PASSWORD_ARGON2_DEFAULT_TIME_COST,
'threads' => \PASSWORD_ARGON2_DEFAULT_THREADS,
];// Either a DateInterval or a DateInterval parsable-string
$defaultLifeTime = null;$splitTokenFactory = new Argon2SplitTokenFactory(/*config: $config, */ $defaultLifeTime);
// Optionally set PSR/Clock compatible instance
// $splitTokenFactory->setClock();// Step 1. Create a new SplitToken for usage
$token = $splitTokenFactory->generate();
// The $authToken holds a \ParagonIE\HiddenString\HiddenString to prevent
// leakage of this value. You need to cast this object to an actual string
// at of usage.
//
// The $authToken is to be shared with the receiver (user) only.
// The value is already encoded as base64 uri-safe string.
//
//
// AGAIN, DO NOT STORE "THIS" VALUE IN THE DATABASE! Store the selector and verifier-hash instead.
//
$authToken = $token->token(); // Returns a \ParagonIE\HiddenString\HiddenString object// Indicate when the token must expire. Note that you need to clear the token from storage yourself.
// Pass null (or leave this method call absent) to never expire the token (not recommended).
//
// If not provided uses "now" + $defaultLifeTime of the factory constructor.
$authToken->expireAt(new \DateTimeImmutable('+1 hour'));// Now to store the token cast the SplitToken to a SplitTokenValueHolder object.
//
// Unlike SplitToken this class is final and doesn't hold the full-token string.
//
// Additionally you store the token with metadata (array only),
// See the linked manual below for more information.
$holder = $token->toValueHolder();// Setting the token would look something like this.
// UPDATE site_user
// SET
// recovery_selector = $holder->selector(),
// recovery_verifier = $holder->verifierHash(),
// recovery_expires_at = $holder->expiresAt(),
// recovery_metadata = json_encode($holder->metadata()),
// recovery_timestamp = NOW()
// WHERE user_id = ...// ----
// Step 2. Reconstruct the SplitToken from a user provided string.
// When the user provides the token verify if it's valid.
// This will throw an exception of token is not of the expected length.$token = $splitTokenFactory->fromString($_GET['token']);
// $result = SELECT user_id, recover_verifier, recovery_expires_at, recovery_metadata WHERE recover_selector = $token->selector()
$holder = new SplitTokenValueHolder($token->selector(), $result['recovery_verifier'], $result['recovery_expires_at'], json_decode($result['recovery_metadata'], true));if ($token->matches($holder)) {
echo 'OK, you have access';
} else {
// Note: Make sure to remove the token from storage.echo 'NO, I cannot let you do this John.';
}
```Once a result is found using the selector, the stored verifier-hash is used to
compute a matching hash of the provided verifier. And the values are compared
in constant-time to protect against side-channel attacks.**See also:**
* [Replacing an existing token](doc/replace-existing-token.md)
* [Using metadata for advanced usage](doc/using-metadata.md)
* [Configuring the hasher](doc/configuring-hasher.md)## Error Handling
Because of security reasons, a `SplitToken` only throws generic runtime
exceptions for wrong usage, but no detailed exceptions about invalid input.In the case of an error the memory allocation of the verifier and full token
is zeroed to prevent leakage during a core dump or unhandled exception.## Versioning
For transparency and insight into the release cycle, and for striving
to maintain backward compatibility, this package is maintained under
the Semantic Versioning guidelines as much as possible.Releases will be numbered with the following format:
`..`
And constructed with the following guidelines:
* Breaking backward compatibility bumps the major (and resets the minor and patch)
* New additions without breaking backward compatibility bumps the minor (and resets the patch)
* Bug fixes and misc changes bumps the patchFor more information on SemVer, please visit .
## Who is behind this library?
This library is brought to you by [Sebastiaan Stok](https://github.com/sstok).
The Split Token idea was first proposed by Paragon Initiative Enterprises.
## License
The Source Code of this package is subject to the terms of the
Mozilla Public License, version 2.0 ([MPLv2.0 License](LICENSE)).Which can be safely used with any other license including MIT
and GNU GPL.[Split Tokens: Token-Based Authentication Protocols without Side-Channels]: https://paragonie.com/blog/2017/02/split-tokens-token-based-authentication-protocols-without-side-channels