Skip to content

Commit

Permalink
Merge remote-tracking branch 'willpower232/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
willpower232 committed Mar 29, 2021
2 parents 1faaf71 + f006e63 commit e15885c
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 170 deletions.
174 changes: 4 additions & 170 deletions README.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
theme: jekyll-theme-minimal

logo: https://raw.githubusercontent.com/RobThree/TwoFactorAuth/master/multifactorauthforeveryone.png
9 changes: 9 additions & 0 deletions docs/_layouts/post.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
layout: default
---

<a href="{{ site.baseurl }}">← contents</a>

<h1>{{ page.title }}</h1>

{{ content }}
54 changes: 54 additions & 0 deletions docs/assets/css/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
---

@import "{{ site.theme }}";

// undo some of the theme to allow code samples to be wider
header {
padding-right: 0;
}
@media print, screen and (min-width: 961px) {
header {
border: 1px solid #e5e5e5;
border-radius: 5px;
margin-bottom: 30px;
margin-right: 30px;
padding-top: 20px;
position: static;
text-align: center;
}
section {
float: none;
width: auto;
}
footer {
float: none;
position: static;
}
}

// ensure code samples can be really wide
.language-php.highlighter-rouge {
clear: both;
}

// add missing consistency
header img {
margin-bottom: 20px;
}

// quick navigation hack needs some spacing
section > a:first-child {
display: block;
margin-bottom:45px;
}

// 100% width is treated like clear which makes it look bad
table {
width: auto;
}

// reset document block whatever so the bullets aren't disturbed by the float
ul {
overflow: hidden;
}
58 changes: 58 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
layout: post
title: Getting Started
---

## 1. Installation

The best way of making use of this project is by installing it with [composer](https://getcomposer.org/doc/01-basic-usage.md).

```
php composer.phar require robthree/twofactorauth
```

or if you have composer installed globally

```
composer require robthree/twofactorauth
```

## 2. Create an instance

Now you can create an instance for use with your code

```php
use RobThree\Auth\TwoFactorAuth;

$tfa = new TwoFactorAuth();
```

**Note:** if you are not using a framework that uses composer, you should [include the composer loader yourself](https://getcomposer.org/doc/01-basic-usage.md#autoloading)

## 3. Shared secrets

When your user is setting up two-factor, or multi-factor, authentication in your project, you can create a secret from the instance.

```php
$secret = $tfa->createSecret();
```

Once you have a secret, it can be communicated to the user however you wish.

```php
<p>Please enter the following code in your app: '<?php echo $secret; ?>'</p>
```

**Note:** until you have verified the user is able to use the secret properly, you should store the secret as part of the current session and not save the secret against your user record.

## 4. Verifying

Having provided the user with the secret, the best practice is to verify their authenticator app can create the appropriate code.

```php
$result = $tfa->verifyCode($secret, $_POST['verification']);
```

If `$result` is `true` then your user has been able to successfully record the `$secret` in their authenticator app and it has generated an appropriate code.

You can now save the `$secret` to your user record and use the same `verifyCode` method each time they log in.
32 changes: 32 additions & 0 deletions docs/improved-code-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
layout: post
title: Improved Code Verification
---

When verifying codes that a user has entered, there are other optional arguments which can improve verification of the code.

```php
$result = $tfa->verifyCode($secret, $_POST['verification'], $discrepancy, $time, &$timeslice);
```

## Discrepancy (default 1)

As the codes that are generated and accepted are consistent within a certain time window (i.e. a timeslice, 30 seconds long by default), it is very important that the server (and the users authenticator app) have the correct time (and date).

The value of `$discrepancy` is the number of timeslices checked in **both** directions of the current one. So when the current time is `14:34:21`, the 'current timeslice' is `14:34:00` to `14:34:30`. If the default is left unchanged, we also verify the code against the timeslice of `14:33:30` to `14:34:00` and for `14:34:30` to `14:35:00`.

This should be sufficient for most cases however you can increase it if you wish. It would be unwise for this to be too high as it could allow a code to be valid for long enough that it could be used fraudulently.

## Time (default null)

The second, `$time`, allows you to check a code for a specific point in time. This argument has no real practical use but can be handy for unit testing. The default value, `null`, means: use the current time.

## Timeslice

`$timeslice` returns a value by reference. The value returned is the timeslice that matched the code (if any) or `0`.

You can store a timeslice alongside the secret and verify that any new timeslice is greater than the existing one.

i.e. if `verifyCode` returns true _and_ the returned timeslice is greater than the last used timeslice for this user/secret then this is the first time the code has been used and you should now store the higher timeslice to verify that the user.

This is an effective defense against a [replay attack](https://en.wikipedia.org/wiki/Replay_attack).
18 changes: 18 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Contents
---

## [The Basics - Getting Started](getting-started.html)

## Advanced Usage

[QR Codes](qr-codes.html)
- [QRServerProvider](qr-codes/qr-server.html)
- [ImageChartsQRCodeProvider](qr-codes/image-charts.html)
- [QRicketProvider](qr-codes/qrickit.html)
- [EndroidQrCodeProvider](qr-codes/endroid.html) (and EndroidQrCodeWithLogoProvider)
- [BaconQRCodeProvider](qr-codes/bacon.html)

[Improved Code Verification](improved-code-verification.html)

[Other Optional Configuration](optional-configuration.html)
56 changes: 56 additions & 0 deletions docs/optional-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
layout: post
title: Optional Configuration
---

## Instance Configuration

The instance (`new TwoFactorAuth()`) can only be configured by the constructor with the following optional arguments

Argument | Default value | Use
------------------|---------------|-----
`$issuer` | `null` | Will be displayed in the users app as the default issuer name when using QR code to import the secret
`$digits` | `6` | The number of digits the resulting codes will be
`$period` | `30` | The number of seconds a code will be valid
`$algorithm` | `'sha1'` | The algorithm used (one of `sha1`, `sha256`, `sha512`, `md5`)
`$qrcodeprovider` | `null` | QR-code provider
`$rngprovider` | `null` | Random Number Generator provider
`$timeprovider` | `null` | Time provider

**Note:** the default values for `$digits`, `$period`, and `$algorithm` provide the widest variety of support amongst common authenticator apps such as Google Authenticator. If you choose to use different values for these arguments you will likely have to instruct your users to use a specific app which supports your chosen configuration.

### RNG providers

This library also comes with some [Random Number Generator (RNG)](https://en.wikipedia.org/wiki/Random_number_generation) providers. The RNG provider generates a number of random bytes and returns these bytes as a string. These values are then used to create the secret. By default (no RNG provider specified) TwoFactorAuth will try to determine the best available RNG provider to use in this order.

1. [CSRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/CSRNGProvider.php) for PHP7+
2. [MCryptRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/MCryptRNGProvider.php) where mcrypt is available
3. [OpenSSLRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/OpenSSLRNGProvider.php) where openssl is available
4. [HashRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/HashRNGProvider.php) **non-cryptographically secure** fallback

Each of these RNG providers have some constructor arguments that allow you to tweak some of the settings to use when creating the random bytes.

You can also implement your own by implementing the [`IRNGProvider` interface](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/IRNGProvider.php).

### Time providers

These allow the TwoFactorAuth library to ensure the servers time is correct (or at least within a margin).

You can use the `ensureCorrectTime()` method to ensure the hosts time is correct. By default this method will compare the hosts time (returned by calling `time()` on the `LocalMachineTimeProvider`) to the default `NTPTimeProvider` and `HttpTimeProvider`.

**Note:** the `NTPTimeProvider` requires your PHP to have the ability to create sockets. If you do not have that ability and wish to use this function, you should pass an array with only an instance of `HttpTimeProvider`.

Alternatively, you can pass an array of classes that implement the [`ITimeProvider` interface](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Time/ITimeProvider.php) to change this and specify the second argument, leniency in seconds (default: 5). An exception will be thrown if the time difference is greater than the leniency.

Ordinarily, you should not need to monitor that the time on the server is correct in this way however if you choose to, we advise to call this method sparingly when relying on 3rd parties (which both the `HttpTimeProvider` and `NTPTimeProvider` do) or, if you need to ensure time is correct on a (very) regular basis to implement an `ITimeProvider` that is more efficient than the built-in ones (making use of a GPS signal for example).

## Secret Configuration

Secrets can be optionally configured with the following optional arguments

Argument | Default value | Use
-----------------------|---------------|-----
`$bits` | `80` | The number of bits (related to the length of the secret)
`$requirecryptosecure` | `true` | Whether you want to require a cryptographically secure source of random numbers

**Note:** as above, these values provide the widest variety of support amongst common authenticator apps however you may choose to increase the value of `$bits` (160 or higher is recommended, see [RFC 4226 - Algorithm Requirements](https://tools.ietf.org/html/rfc4226#section-4)) as long as it is set to a multiple of 8.
61 changes: 61 additions & 0 deletions docs/qr-codes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
layout: post
title: QR Codes
---

An alternative way of communicating the secret to the user is through the use of [QR Codes](http://en.wikipedia.org/wiki/QR_code) which most if not all authenticator mobile apps can scan.

This can avoid accidental typing errors and also pre-set some text values within the users app.

You can display the QR Code as a base64 encoded image using the instance as follows, supplying the users name or other public identifier as the first argument

````php
<p>Scan the following image with your app:</p>
<img src="<?php echo $tfa->getQRCodeImageAsDataUri('Bob Ross', $secret); ?>">
````

You can also specify a size as a third argument which is 200 by default.

**Note:** by default, the QR code returned by the instance is generated from a third party across the internet. If the third party is encountering problems or is not available from where you have hosted your code, your user will likely experience a delay in seeing the QR code, if it even loads at all. This can be overcome with offline providers configured when you create the instance.

## Online Providers

[QRServerProvider](qr-codes/qr-server.html) (default)

[ImageChartsQRCodeProvider](qr-codes/image-charts.html)

[QRicketProvider](qr-codes/qrickit.html)

## Offline Providers

[EndroidQrCodeProvider](qr-codes/endroid.html) and EndroidQrCodeWithLogoProvider

[BaconQRCodeProvider](qr-codes/bacon.html)

**Note:** offline providers may have additional PHP requirements in order to function, you should study what is required before trying to make use of them.

## Custom Provider

If you wish to make your own QR Code provider to reference another service or library, it must implement the [IQRCodeProvider interface](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Qr/IQRCodeProvider.php).

It is recommended to use similar constructor arguments as the included providers to avoid big shifts when trying different providers.

## Using a specific provider

If you do not want to use the default QR code provider, you can specify the one you want to use when you create your instance.

```php
use RobThree\Auth\TwoFactorAuth;

$qrCodeProvider = new YourChosenProvider();

$tfa = new TwoFactorAuth(
null,
6,
30,
'sha1',
$qrCodeProvider
);
```

As you create a new instance of your provider, you can supply any extra configuration there.
23 changes: 23 additions & 0 deletions docs/qr-codes/bacon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
layout: post
title: bacon/bacon-qr-code
---

## Installation

In order to use this provider, you will need to install the library at version 2 (or later) and its dependencies

```
composer require bacon/bacon-qr-code ^2.0
```

You will also need the PHP imagick extension **if** you aren't using the SVG format.

## Optional Configuration

Argument | Default value
--------------------|---------------
`$borderWidth` | `4`
`$backgroundColour` | `'#ffffff'`
`$foregroundColour` | `'#000000'`
`$format` | `'png'`
37 changes: 37 additions & 0 deletions docs/qr-codes/endroid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
layout: post
title: endroid/qr-code
---

## Installation

In order to use this provider, you will need to install the library at version 3 and its dependencies

```
composer require endroid/qr-code ^3.0
```

You will also need the PHP gd extension installing.

## Optional Configuration

Argument | Default value
------------------------|---------------
`$bgcolor` | `'ffffff'`
`$color` | `'000000'`
`$margin` | `0`
`$errorcorrectionlevel` | `'H'`

## Logo

If you make use of `EndroidQrCodeWithLogoProvider` then you have access to the `setLogo` function on the provider so you may add a logo to the centre of your QR code.

```php
use RobThree\Auth\TwoFactorAuth\Providers\Qr\EndroidQrCodeWithLogoProvider;

$qrCodeProvider = new EndroidQrCodeWithLogoProvider();

$qrCodeProvider->setLogo('/path/to/your/image');
```

You can see how to also set the size of the logo in the [source code](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php).
16 changes: 16 additions & 0 deletions docs/qr-codes/image-charts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
layout: post
title: Image-Charts
---

## Optional Configuration

Argument | Default value
------------------------|---------------
`$verifyssl` | `false`
`$errorcorrectionlevel` | `'L'`
`$margin` | `4`

`$verifyssl` is used internally to help guarantee the security of the connection. It is possible that where you are running the code from will have problems verifying an SSL connection so if you know this is not the case, you can supply `true`.

The other parameters are passed to [Image-Charts](https://documentation.image-charts.com/qr-codes/) so you can refer to them for more detail on how the values are used.
20 changes: 20 additions & 0 deletions docs/qr-codes/qr-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
layout: post
title: QR Server
---

## Optional Configuration

Argument | Default value
------------------------|---------------
`$verifyssl` | `false`
`$errorcorrectionlevel` | `'L'`
`$margin` | `4`
`$qzone` | `1`
`$bgcolor` | `'ffffff'`
`$color` | `'000000'`
`$format` | `'png'`

`$verifyssl` is used internally to help guarantee the security of the connection. It is possible that where you are running the code from will have problems verifying an SSL connection so if you know this is not the case, you can supply `true`.

The other parameters are passed to [goqr.me](http://goqr.me/api/doc/create-qr-code/) so you can refer to them for more detail on how the values are used.
Loading

0 comments on commit e15885c

Please sign in to comment.