Skip to content

Commit e15885c

Browse files
committed
Merge remote-tracking branch 'willpower232/master'
2 parents 1faaf71 + f006e63 commit e15885c

14 files changed

+406
-170
lines changed

README.md

Lines changed: 4 additions & 170 deletions
Large diffs are not rendered by default.

docs/_config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
theme: jekyll-theme-minimal
2+
3+
logo: https://raw.githubusercontent.com/RobThree/TwoFactorAuth/master/multifactorauthforeveryone.png

docs/_layouts/post.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
layout: default
3+
---
4+
5+
<a href="{{ site.baseurl }}">← contents</a>
6+
7+
<h1>{{ page.title }}</h1>
8+
9+
{{ content }}

docs/assets/css/style.scss

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
---
3+
4+
@import "{{ site.theme }}";
5+
6+
// undo some of the theme to allow code samples to be wider
7+
header {
8+
padding-right: 0;
9+
}
10+
@media print, screen and (min-width: 961px) {
11+
header {
12+
border: 1px solid #e5e5e5;
13+
border-radius: 5px;
14+
margin-bottom: 30px;
15+
margin-right: 30px;
16+
padding-top: 20px;
17+
position: static;
18+
text-align: center;
19+
}
20+
section {
21+
float: none;
22+
width: auto;
23+
}
24+
footer {
25+
float: none;
26+
position: static;
27+
}
28+
}
29+
30+
// ensure code samples can be really wide
31+
.language-php.highlighter-rouge {
32+
clear: both;
33+
}
34+
35+
// add missing consistency
36+
header img {
37+
margin-bottom: 20px;
38+
}
39+
40+
// quick navigation hack needs some spacing
41+
section > a:first-child {
42+
display: block;
43+
margin-bottom:45px;
44+
}
45+
46+
// 100% width is treated like clear which makes it look bad
47+
table {
48+
width: auto;
49+
}
50+
51+
// reset document block whatever so the bullets aren't disturbed by the float
52+
ul {
53+
overflow: hidden;
54+
}

docs/getting-started.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
layout: post
3+
title: Getting Started
4+
---
5+
6+
## 1. Installation
7+
8+
The best way of making use of this project is by installing it with [composer](https://getcomposer.org/doc/01-basic-usage.md).
9+
10+
```
11+
php composer.phar require robthree/twofactorauth
12+
```
13+
14+
or if you have composer installed globally
15+
16+
```
17+
composer require robthree/twofactorauth
18+
```
19+
20+
## 2. Create an instance
21+
22+
Now you can create an instance for use with your code
23+
24+
```php
25+
use RobThree\Auth\TwoFactorAuth;
26+
27+
$tfa = new TwoFactorAuth();
28+
```
29+
30+
**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)
31+
32+
## 3. Shared secrets
33+
34+
When your user is setting up two-factor, or multi-factor, authentication in your project, you can create a secret from the instance.
35+
36+
```php
37+
$secret = $tfa->createSecret();
38+
```
39+
40+
Once you have a secret, it can be communicated to the user however you wish.
41+
42+
```php
43+
<p>Please enter the following code in your app: '<?php echo $secret; ?>'</p>
44+
```
45+
46+
**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.
47+
48+
## 4. Verifying
49+
50+
Having provided the user with the secret, the best practice is to verify their authenticator app can create the appropriate code.
51+
52+
```php
53+
$result = $tfa->verifyCode($secret, $_POST['verification']);
54+
```
55+
56+
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.
57+
58+
You can now save the `$secret` to your user record and use the same `verifyCode` method each time they log in.

docs/improved-code-verification.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
layout: post
3+
title: Improved Code Verification
4+
---
5+
6+
When verifying codes that a user has entered, there are other optional arguments which can improve verification of the code.
7+
8+
```php
9+
$result = $tfa->verifyCode($secret, $_POST['verification'], $discrepancy, $time, &$timeslice);
10+
```
11+
12+
## Discrepancy (default 1)
13+
14+
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).
15+
16+
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`.
17+
18+
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.
19+
20+
## Time (default null)
21+
22+
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.
23+
24+
## Timeslice
25+
26+
`$timeslice` returns a value by reference. The value returned is the timeslice that matched the code (if any) or `0`.
27+
28+
You can store a timeslice alongside the secret and verify that any new timeslice is greater than the existing one.
29+
30+
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.
31+
32+
This is an effective defense against a [replay attack](https://en.wikipedia.org/wiki/Replay_attack).

docs/index.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: Contents
3+
---
4+
5+
## [The Basics - Getting Started](getting-started.html)
6+
7+
## Advanced Usage
8+
9+
[QR Codes](qr-codes.html)
10+
- [QRServerProvider](qr-codes/qr-server.html)
11+
- [ImageChartsQRCodeProvider](qr-codes/image-charts.html)
12+
- [QRicketProvider](qr-codes/qrickit.html)
13+
- [EndroidQrCodeProvider](qr-codes/endroid.html) (and EndroidQrCodeWithLogoProvider)
14+
- [BaconQRCodeProvider](qr-codes/bacon.html)
15+
16+
[Improved Code Verification](improved-code-verification.html)
17+
18+
[Other Optional Configuration](optional-configuration.html)

docs/optional-configuration.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
layout: post
3+
title: Optional Configuration
4+
---
5+
6+
## Instance Configuration
7+
8+
The instance (`new TwoFactorAuth()`) can only be configured by the constructor with the following optional arguments
9+
10+
Argument | Default value | Use
11+
------------------|---------------|-----
12+
`$issuer` | `null` | Will be displayed in the users app as the default issuer name when using QR code to import the secret
13+
`$digits` | `6` | The number of digits the resulting codes will be
14+
`$period` | `30` | The number of seconds a code will be valid
15+
`$algorithm` | `'sha1'` | The algorithm used (one of `sha1`, `sha256`, `sha512`, `md5`)
16+
`$qrcodeprovider` | `null` | QR-code provider
17+
`$rngprovider` | `null` | Random Number Generator provider
18+
`$timeprovider` | `null` | Time provider
19+
20+
**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.
21+
22+
### RNG providers
23+
24+
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.
25+
26+
1. [CSRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/CSRNGProvider.php) for PHP7+
27+
2. [MCryptRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/MCryptRNGProvider.php) where mcrypt is available
28+
3. [OpenSSLRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/OpenSSLRNGProvider.php) where openssl is available
29+
4. [HashRNGProvider](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/HashRNGProvider.php) **non-cryptographically secure** fallback
30+
31+
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.
32+
33+
You can also implement your own by implementing the [`IRNGProvider` interface](https://github.com/RobThree/TwoFactorAuth/blob/master/lib/Providers/Rng/IRNGProvider.php).
34+
35+
### Time providers
36+
37+
These allow the TwoFactorAuth library to ensure the servers time is correct (or at least within a margin).
38+
39+
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`.
40+
41+
**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`.
42+
43+
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.
44+
45+
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).
46+
47+
## Secret Configuration
48+
49+
Secrets can be optionally configured with the following optional arguments
50+
51+
Argument | Default value | Use
52+
-----------------------|---------------|-----
53+
`$bits` | `80` | The number of bits (related to the length of the secret)
54+
`$requirecryptosecure` | `true` | Whether you want to require a cryptographically secure source of random numbers
55+
56+
**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.

docs/qr-codes.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
layout: post
3+
title: QR Codes
4+
---
5+
6+
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.
7+
8+
This can avoid accidental typing errors and also pre-set some text values within the users app.
9+
10+
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
11+
12+
````php
13+
<p>Scan the following image with your app:</p>
14+
<img src="<?php echo $tfa->getQRCodeImageAsDataUri('Bob Ross', $secret); ?>">
15+
````
16+
17+
You can also specify a size as a third argument which is 200 by default.
18+
19+
**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.
20+
21+
## Online Providers
22+
23+
[QRServerProvider](qr-codes/qr-server.html) (default)
24+
25+
[ImageChartsQRCodeProvider](qr-codes/image-charts.html)
26+
27+
[QRicketProvider](qr-codes/qrickit.html)
28+
29+
## Offline Providers
30+
31+
[EndroidQrCodeProvider](qr-codes/endroid.html) and EndroidQrCodeWithLogoProvider
32+
33+
[BaconQRCodeProvider](qr-codes/bacon.html)
34+
35+
**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.
36+
37+
## Custom Provider
38+
39+
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).
40+
41+
It is recommended to use similar constructor arguments as the included providers to avoid big shifts when trying different providers.
42+
43+
## Using a specific provider
44+
45+
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.
46+
47+
```php
48+
use RobThree\Auth\TwoFactorAuth;
49+
50+
$qrCodeProvider = new YourChosenProvider();
51+
52+
$tfa = new TwoFactorAuth(
53+
null,
54+
6,
55+
30,
56+
'sha1',
57+
$qrCodeProvider
58+
);
59+
```
60+
61+
As you create a new instance of your provider, you can supply any extra configuration there.

docs/qr-codes/bacon.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
layout: post
3+
title: bacon/bacon-qr-code
4+
---
5+
6+
## Installation
7+
8+
In order to use this provider, you will need to install the library at version 2 (or later) and its dependencies
9+
10+
```
11+
composer require bacon/bacon-qr-code ^2.0
12+
```
13+
14+
You will also need the PHP imagick extension **if** you aren't using the SVG format.
15+
16+
## Optional Configuration
17+
18+
Argument | Default value
19+
--------------------|---------------
20+
`$borderWidth` | `4`
21+
`$backgroundColour` | `'#ffffff'`
22+
`$foregroundColour` | `'#000000'`
23+
`$format` | `'png'`

docs/qr-codes/endroid.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
layout: post
3+
title: endroid/qr-code
4+
---
5+
6+
## Installation
7+
8+
In order to use this provider, you will need to install the library at version 3 and its dependencies
9+
10+
```
11+
composer require endroid/qr-code ^3.0
12+
```
13+
14+
You will also need the PHP gd extension installing.
15+
16+
## Optional Configuration
17+
18+
Argument | Default value
19+
------------------------|---------------
20+
`$bgcolor` | `'ffffff'`
21+
`$color` | `'000000'`
22+
`$margin` | `0`
23+
`$errorcorrectionlevel` | `'H'`
24+
25+
## Logo
26+
27+
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.
28+
29+
```php
30+
use RobThree\Auth\TwoFactorAuth\Providers\Qr\EndroidQrCodeWithLogoProvider;
31+
32+
$qrCodeProvider = new EndroidQrCodeWithLogoProvider();
33+
34+
$qrCodeProvider->setLogo('/path/to/your/image');
35+
```
36+
37+
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).

docs/qr-codes/image-charts.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
layout: post
3+
title: Image-Charts
4+
---
5+
6+
## Optional Configuration
7+
8+
Argument | Default value
9+
------------------------|---------------
10+
`$verifyssl` | `false`
11+
`$errorcorrectionlevel` | `'L'`
12+
`$margin` | `4`
13+
14+
`$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`.
15+
16+
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.

docs/qr-codes/qr-server.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
layout: post
3+
title: QR Server
4+
---
5+
6+
## Optional Configuration
7+
8+
Argument | Default value
9+
------------------------|---------------
10+
`$verifyssl` | `false`
11+
`$errorcorrectionlevel` | `'L'`
12+
`$margin` | `4`
13+
`$qzone` | `1`
14+
`$bgcolor` | `'ffffff'`
15+
`$color` | `'000000'`
16+
`$format` | `'png'`
17+
18+
`$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`.
19+
20+
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.

0 commit comments

Comments
 (0)