PHPackages                             tbaumgard/yubilib - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. tbaumgard/yubilib

ActiveLibrary[Security](/categories/security)

tbaumgard/yubilib
=================

YubiKey one-time password (OTP) validation, YubiKey emulator, and format validation

v1.0.1(6y ago)03BSD-3-ClausePHPPHP &gt;=5.6.0

Since Mar 29Pushed 6y ago1 watchersCompare

[ Source](https://github.com/tbaumgard/yubilib)[ Packagist](https://packagist.org/packages/tbaumgard/yubilib)[ Docs](https://github.com/tbaumgard/yubilib)[ RSS](/packages/tbaumgard-yubilib/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (2)Dependencies (1)Versions (3)Used By (0)

yubilib
=======

[](#yubilib)

`yubilib` is a PHP library for remotely and locally validating [YubiKey](https://www.yubico.com/products/yubikey-hardware/) one-time passwords (OTPs). It also includes a YubiKey emulator for testing and development as well as functions to check whether the various components of a one-time password are in the correct format.

Documentation
-------------

[](#documentation)

HTML-formatted documentation can be generated using [Doxygen](http://www.stack.nl/~dimitri/doxygen/) and the included `Doxyfile` file. The generated documentation is placed in the `documentation/html` directory, and the main page can be found at `documentation/html/index.html`.

Example Usage
-------------

[](#example-usage)

### Remote Validation

[](#remote-validation)

Validating a one-time password using a validation server is fairly straightforward. First, either [get a client ID and API key](https://upgrade.yubico.com/getapikey/) to use [Yubico's YubiCloud](https://www.yubico.com/products/services-software/yubicloud/) validation servers or [host a validation server yourself](https://developers.yubico.com/Software_Projects/Yubico_OTP/YubiCloud_Validation_Servers/).

Then, simply make a call to the server with those credentials:

```
// Load the library and automatically load classes and dependencies as needed.
require_once "path/to/yubilib/vendor/autoload.php";

$otp = "kgucftudgcknghjjkunucgldkcvdtfhnbuikidrlnukt";
$settings["clientId"] = "12345";
$settings["apiKey"] = "IEFQSSBrZXkgaW4gYmFzZTY0IA==";
$settings["server"] = "api.yubico.com";
$settings["timeout"] = 10;

try {
	$isOtpValid = yubilib\validateOneTimePasswordRemotely($otp, $settings);
} catch (yubilib\requestTimeoutException $exception) {
	// Handle a request that timed out.
} catch (yubilib\badRequestException $exception) {
	// Handle a bad request, e.g., invalid server, client ID, or API key.
} catch (yubilib\badResponseException $exception) {
	// Handle a bad response, e.g., network or validation server issue.
}
```

### Local Validation

[](#local-validation)

#### Storing Credentials

[](#storing-credentials)

To be able to validate a one-time password, your application must first have credentials stored somewhere. `yubilib` includes functions to make this easier. For example:

```
// Load the library and automatically load classes and dependencies as needed.
require_once "path/to/yubilib/vendor/autoload.php";

$userId = 12345;
$credentials["publicIdentity"] = "kgucftudgckn";
$credentials["privateIdentity"] = "4ae4e40efa8a";
$credentials["secretKey"] = "637f70b3846347d55ee49016a7da70a2";
$credentials["counter"] = 0;

// Prepare the credentials to get them into the format that
// yubilib\serializeCredentials() and yubilib\validateOneTimePasswordLocally()
// expect. This includes hashing the private identity as a security measure.
$preparedCredentials = yubilib\prepareCredentialsForSerialization($credentials);

// Serialize the credentials to a string for easy storage.
$serializedCredentials = yubilib\serializeCredentials($credentials);

// Store the serialized credentials somewhere safe.
example\storeOneTimePasswordCredentials($userId, $serializedCredentials);
```

**Security Notice**: it is *absolutely essential* that the credentials are stored in a secure and encrypted manner. If you're unsure how to do that properly, use remote validation and the YubiCloud validation servers instead.

#### Validating a One-Time Password

[](#validating-a-one-time-password)

Once the credentials have been stored securely, validating a one-time password is pretty straightforward:

```
// Load the library and automatically load classes and dependencies as needed.
require_once "path/to/yubilib/vendor/autoload.php";

$userId = 12345;
$otp = "kgucftudgcknghjjkunucgldkcvdtfhnbuikidrlnukt";

// Retrieve the stored credentials in serialized format.
$serializedCredentials = example\retriveOneTimePasswordCredentials($userId);

// Deserialize and validate the one-time password.
$credentials = yubilib\deserializeCredentials($serializedCredentials);
list($isOtpValid, $newCounter) = yubilib\validateOneTimePasswordLocally($otp, $credentials);

if ($isOtpValid) {
	// Update the counter and serialize the updated credentials.
	$credentials["counter"] = $newCounter;
	$serializedCredentials = yubilib\serializeCredentials($credentials);

	// Save the updated credentials, namely the counter, to prevent replay attacks.
	example\storeOneTimePasswordCredentials($userId, $serializedCredentials);
} else {
	// Notify the user that the one-time password is invalid.
	example\printOneTimePasswordErrorMessage();
}
```

#### Format Validation

[](#format-validation)

The library also includes functions to validate the format of one-time passwords and their various components. Here are some examples:

```
// Load the library and automatically load classes and dependencies as needed.
require_once "path/to/yubilib/vendor/autoload.php";

$publicIdentity = "kgucftudgckn";
$privateIdentity = "4ae4e40efa8a";
$secretKey = "637f70b3846347d55ee49016a7da70a2";
$otp = "kgucftudgcknghjjkunucgldkcvdtfhnbuikidrlnukt";

if (yubilib\isPublicIdentity($publicIdentity, "modhex")) {
	// Notify the user that the public identity is invalid.
	example\printPublicIdentityErrorMessage();
}

if (yubilib\isPrivateIdentity($privateIdentity, "hex")) {
	// Notify the user that the private identity is invalid.
	example\printPrivateIdentityErrorMessage();
}

if (yubilib\isSecretKey($secretKey, "hex")) {
	// Notify the user that the secret key is invalid.
	example\printSecretKeyErrorMessage();
}

if (yubilib\isOneTimePassword($otp, "modhex")) {
	// Notify the user that the one-time password is invalid.
	example\printOneTimePasswordErrorMessage();
}
```

#### Emulator

[](#emulator)

The `emulator.php` file contains a YubiKey emulator for testing and development purposes. By default, this file doesn't do anything in order to prevent abuse if this file is made publicly available, e.g., on a website. You must first comment out the `return` statement at the beginning of the file to use the emulator.

Once that is done, you can modify the values in `emulator.php` and run it to generate and print a one-time password.

Notes
-----

[](#notes)

- Your application should include some kind of recovery mechanism for users who lose their YubiKeys.
- Your application should mitigate brute-force and other attacks by only allowing a specific amount of login attempts during a specific time interval.
- With regards to local validation, it is *absolutely essential* that the credentials are stored in a secure and encrypted manner. If you're unsure how to do that properly, use remote validation and the YubiCloud validation servers instead.
- In the interest of full disclosure, this library hasn't gone through a third-party security audit.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1101 days

Total

2

Last Release

2230d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a4aa50528c742a55d0348c0d7a0c14bfcca74574914140366b40562314defadd?d=identicon)[tbaumgard](/maintainers/tbaumgard)

---

Top Contributors

[![tbaumgard](https://avatars.githubusercontent.com/u/1239241?v=4)](https://github.com/tbaumgard "tbaumgard (3 commits)")

---

Tags

phpsecurityyubikey

### Embed Badge

![Health badge](/badges/tbaumgard-yubilib/health.svg)

```
[![Health](https://phpackages.com/badges/tbaumgard-yubilib/health.svg)](https://phpackages.com/packages/tbaumgard-yubilib)
```

###  Alternatives

[phpseclib/phpseclib

PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.

5.6k434.8M1.3k](/packages/phpseclib-phpseclib)[paragonie/paseto

Platform-Agnostic Security Tokens

3.4k1.3M18](/packages/paragonie-paseto)[paragonie/ciphersweet

Searchable field-level encryption library for relational databases

4641.2M21](/packages/paragonie-ciphersweet)[paragonie/certainty

Up-to-date, verifiable repository for Certificate Authorities

2642.4M20](/packages/paragonie-certainty)[paragonie/hidden-string

Encapsulate strings in an object to hide them from stack traces

7410.6M39](/packages/paragonie-hidden-string)[paragonie/anti-csrf

Paragon Initiative's Anti-CSRF Security Library

307200.6k5](/packages/paragonie-anti-csrf)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
