Never Ending Security

It starts all here

TokID / IdFix- a PGP based web authentication token

IdFix: a PGP web authentication token

Author: Julien Vehent <jvehent@mozilla.com>
Date: 2015-02-23
Version: 1

IdFix proposes a method for generating and verifying authentication tokens using PGP. Its primary application is authenticating users on web APIs by sending an authentication token in the X-IDFIX HTTP header.

1   Motivation

IdFix was primarily designed for Mozilla InvestiGator as a way to authenticate users of the API without requiring them to enter credentials. IdFix has since been generalized to be used in any application that can emit and verify OpenPGP signatures.

A signed IdFix token transports the identity of the owner of an OpenPGP private key, which can be a human or a machine. A signed token is generated programmatically using the private keystore or GPG agent of a client. IdFix alleviates the need for a client to enter credentials during authentication, modulo any passphrase required to access the private key of the user (users should use a GPG Agent to prevent this).

When used on a secure channel, IdFix guarantees that the owner of a private key emitted a given request. It is up to the application to associate the identity carried by IdFix with proper accesses. We recommend to do this by comparing the key fingerprint that emitted a given signature against fingerprints of users stored in a database.

2   Security considerations

2.1   Replay attacks

In the IdFix protocol, protection against replay attacks is optional. A verifier may decide to permit token replay to allow signers to reuse tokens multiple times, and thus reduce the cost of generating tokens with every request.

In this mode, IdFix is vulnerable to replay attacks. It is therefore critical that a signed IdFix token is transmitted over a security channel, such as HTTPS. IdFix assumes that a token is only readable by its sender and receiver, and does not provide protection against token theft. We considers that HTTPS is sufficiently widespread that IdFix doesn’t need to provide protection against token theft.

A verifier may decide to implement replay protection by discarding token nonces that have already been consumed once. This mode assumes that the verifier keeps track of receives IdFix tokens for a given period of time.

2.2   PGP Fingerprint comparison

It must be noted that, when comparing PGP Fingerprints, the full 40 bytes of a given fingerprint must be used. Short IDs, commonly used to reference PGP keys, must be avoided as they are highly prone to collisions.

2.3   Time synchronization

IdFix requires the uses of a timestamp in RFC3339 format, and allows verifiers to discard tokens with timestamps outside of an acceptable time window. It is expected that clients (signers) and servers (verifiers) will be synchronized on a reliable time source, for example using NTP. Failure to synchronize on a reliable time source may lead to authentication failures.

3   Terminology

  • signer: a client that generates and signs an IdFix token
  • verifier: a server that receives and verifies an IdFix token
  • origin string: the cleartext string used by the signer to create an IdFix token
  • signature: an OpenPGP armored signature of the origin string, computed using the signer’s private key

4   Format

A signed IdFix token is a string that contains the following information:

  • version number
  • UTC timestamp in RFC3339 format
  • random nonce of at least 64 bits (preferred 128 bits)
  • armored signature of the three fields above, signed by a private key

An example token looks like the following:

`1;2006-01-02T15:04:05Z;1424703763646749449812569234;owEBYQGe/pANAwAIAaPWUhc7dj6...<truncated>`

Over HTTP, the IdFix protocol recommends to send the signed token in a HTTP header named X-IDFIX for interoperability.

5   Construction

An IdFix signed token is made of two parts: * an origin string composed of a version number, a timestamp and a nonce * an armored signature of the cleartext string

5.1   Origin string

Construction of a token starts by building the origin string using the following requirements:

  • the current version of IdFix is 1
  • the nonce value must be a random positive integer
  • the timestamp must be in the UTC timezone and follow the format defined in RFC3339
  • each component must be followed by a semicolon ; (ascii code 0x3B)
  • the origin string must be terminated by a newline character n (ascii code 0x0A)

A random nonce can be generated in bash with the command below ($RANDOM returns a 16 bits integer, so we invoke it 8 times to get 128 bits).

echo $RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM$RANDOM

A correct timestamp can be generated with the following bash command:

$ date -u +%Y-%m-%dT%H:%M:%SZ

An example of origin string is:

1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;

The hexadecimal version of which is represented below:

$ hexdump -C <<< '1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;'
00000000  31 3b 32 30 30 36 2d 30  31 2d 30 32 54 31 35 3a  |1;2006-01-02T15:|
00000010  30 34 3a 30 35 5a 3b 31  38 32 35 39 32 32 38 30  |04:05Z;182592280|
00000020  37 34 39 30 36 33 30 30  31 37 35 36 30 34 33 36  |7490630017560436|
00000030  34 30 31 32 33 37 34 39  33 36 35 30 35 39 3b 0a  |40123749365059;.|
0000003f

5.2   Signature of the origin string

The origin string constructed above must be signed using the digital signature method described in RFC 4880: OpenPGP Message Format. All acceptable OpenPGP signatures are authorized.

The signature must be detached and unwrapped into a single string, omitting the PGP SIGNATURE header and footer, Version line and blank lines, as follows:

  1. Create a detached signature of the origin string
$ gpg -a --detach-sig <<< '1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;'

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAABCAAGBQJU6+ZCAAoJEKPWUhc7dj6PsooH/3VLFc2gOL0ysHeLNZ8/UyWQ
7ZPt7guubKj3BXEb0C55yTM1ZV+ki9fjbf9BSfPHJLk+9PtmUEgLUkVZupJNXmRS
vKc0nQRFGiEB5rliN/9sF4vDMyVvFQ20SVSc36TCVcgi/LpicfT6Wonq/XB/JtDd
KD2SIheoOW0LAauEeRQGdmm42ByTC5zvL3Y3a/oKP359FEIgZKGXvk0WpBFsX5VM
9w4L6+PsvMIhTx1lOOVIZaCClgLjsofmPfaaPAYLbHf81GGQ/9cT4SkGSyiXbSFA
gWTPMEkZ8KUW4hTONDxDEoi7lFs2nudqb6fK21QjN55Yly4goTLT/FlrCJCQN6k=
=pStP
-----END PGP SIGNATURE-----
  1. Unwrap the signature data into a single string, without the lines —–BEGIN PGP SIGNATURE—–, Version: GnuPG v1, blank line, and —–END PGP SIGNATURE—–.
iQEcBAABCAAGBQJU6+ZCAAoJEKPWUhc7dj6PsooH/3VLFc2gOL0ysHeLNZ8/UyWQ7ZPt7guubKj3BXEb0C55yTM1ZV+ki9fjbf9BSfPHJLk+9PtmUEgLUkVZupJNXmRSvKc0nQRFGiEB5rliN/9sF4vDMyVvFQ20SVSc36TCVcgi/LpicfT6Wonq/XB/JtDdKD2SIheoOW0LAauEeRQGdmm42ByTC5zvL3Y3a/oKP359FEIgZKGXvk0WpBFsX5VM9w4L6+PsvMIhTx1lOOVIZaCClgLjsofmPfaaPAYLbHf81GGQ/9cT4SkGSyiXbSFAgWTPMEkZ8KUW4hTONDxDEoi7lFs2nudqb6fK21QjN55Yly4goTLT/FlrCJCQN6k==pStP

5.3   Token assembly

An IdFix token is finally build by concatenating the origin string and the signature. The trailing newline n of the origin string is removed before concatenating the signature, as follows:

1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;iQEcBAABCAAGBQJU6+ZCAAoJEKPWUhc7dj6PsooH/3VLFc2gOL0ysHeLNZ8/UyWQ7ZPt7guubKj3BXEb0C55yTM1ZV+ki9fjbf9BSfPHJLk+9PtmUEgLUkVZupJNXmRSvKc0nQRFGiEB5rliN/9sF4vDMyVvFQ20SVSc36TCVcgi/LpicfT6Wonq/XB/JtDdKD2SIheoOW0LAauEeRQGdmm42ByTC5zvL3Y3a/oKP359FEIgZKGXvk0WpBFsX5VM9w4L6+PsvMIhTx1lOOVIZaCClgLjsofmPfaaPAYLbHf81GGQ/9cT4SkGSyiXbSFAgWTPMEkZ8KUW4hTONDxDEoi7lFs2nudqb6fK21QjN55Yly4goTLT/FlrCJCQN6k==pStP

The hexadecimal version of which is represented below:

$ hexdump -C <<< '1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;iQEcBAABCAAGBQJU6+ZCAAoJEKPWUhc7dj6PsooH/3VLFc2gOL0ysHeLNZ8/UyWQ7ZPt7guubKj3BXEb0C55yTM1ZV+ki9fjbf9BSfPHJLk+9PtmUEgLUkVZupJNXmRSvKc0nQRFGiEB5rliN/9sF4vDMyVvFQ20SVSc36TCVcgi/LpicfT6Wonq/XB/JtDdKD2SIheoOW0LAauEeRQGdmm42ByTC5zvL3Y3a/oKP359FEIgZKGXvk0WpBFsX5VM9w4L6+PsvMIhTx1lOOVIZaCClgLjsofmPfaaPAYLbHf81GGQ/9cT4SkGSyiXbSFAgWTPMEkZ8KUW4hTONDxDEoi7lFs2nudqb6fK21QjN55Yly4goTLT/FlrCJCQN6k==pStP'
00000000  31 3b 32 30 30 36 2d 30  31 2d 30 32 54 31 35 3a  |1;2006-01-02T15:|
00000010  30 34 3a 30 35 5a 3b 31  38 32 35 39 32 32 38 30  |04:05Z;182592280|
00000020  37 34 39 30 36 33 30 30  31 37 35 36 30 34 33 36  |7490630017560436|
00000030  34 30 31 32 33 37 34 39  33 36 35 30 35 39 3b 69  |40123749365059;i|
00000040  51 45 63 42 41 41 42 43  41 41 47 42 51 4a 55 36  |QEcBAABCAAGBQJU6|
00000050  2b 5a 43 41 41 6f 4a 45  4b 50 57 55 68 63 37 64  |+ZCAAoJEKPWUhc7d|
00000060  6a 36 50 73 6f 6f 48 2f  33 56 4c 46 63 32 67 4f  |j6PsooH/3VLFc2gO|
00000070  4c 30 79 73 48 65 4c 4e  5a 38 2f 55 79 57 51 37  |L0ysHeLNZ8/UyWQ7|
00000080  5a 50 74 37 67 75 75 62  4b 6a 33 42 58 45 62 30  |ZPt7guubKj3BXEb0|
00000090  43 35 35 79 54 4d 31 5a  56 2b 6b 69 39 66 6a 62  |C55yTM1ZV+ki9fjb|
000000a0  66 39 42 53 66 50 48 4a  4c 6b 2b 39 50 74 6d 55  |f9BSfPHJLk+9PtmU|
000000b0  45 67 4c 55 6b 56 5a 75  70 4a 4e 58 6d 52 53 76  |EgLUkVZupJNXmRSv|
000000c0  4b 63 30 6e 51 52 46 47  69 45 42 35 72 6c 69 4e  |Kc0nQRFGiEB5rliN|
000000d0  2f 39 73 46 34 76 44 4d  79 56 76 46 51 32 30 53  |/9sF4vDMyVvFQ20S|
000000e0  56 53 63 33 36 54 43 56  63 67 69 2f 4c 70 69 63  |VSc36TCVcgi/Lpic|
000000f0  66 54 36 57 6f 6e 71 2f  58 42 2f 4a 74 44 64 4b  |fT6Wonq/XB/JtDdK|
00000100  44 32 53 49 68 65 6f 4f  57 30 4c 41 61 75 45 65  |D2SIheoOW0LAauEe|
00000110  52 51 47 64 6d 6d 34 32  42 79 54 43 35 7a 76 4c  |RQGdmm42ByTC5zvL|
00000120  33 59 33 61 2f 6f 4b 50  33 35 39 46 45 49 67 5a  |3Y3a/oKP359FEIgZ|
00000130  4b 47 58 76 6b 30 57 70  42 46 73 58 35 56 4d 39  |KGXvk0WpBFsX5VM9|
00000140  77 34 4c 36 2b 50 73 76  4d 49 68 54 78 31 6c 4f  |w4L6+PsvMIhTx1lO|
00000150  4f 56 49 5a 61 43 43 6c  67 4c 6a 73 6f 66 6d 50  |OVIZaCClgLjsofmP|
00000160  66 61 61 50 41 59 4c 62  48 66 38 31 47 47 51 2f  |faaPAYLbHf81GGQ/|
00000170  39 63 54 34 53 6b 47 53  79 69 58 62 53 46 41 67  |9cT4SkGSyiXbSFAg|
00000180  57 54 50 4d 45 6b 5a 38  4b 55 57 34 68 54 4f 4e  |WTPMEkZ8KUW4hTON|
00000190  44 78 44 45 6f 69 37 6c  46 73 32 6e 75 64 71 62  |DxDEoi7lFs2nudqb|
000001a0  36 66 4b 32 31 51 6a 4e  35 35 59 6c 79 34 67 6f  |6fK21QjN55Yly4go|
000001b0  54 4c 54 2f 46 6c 72 43  4a 43 51 4e 36 6b 3d 3d  |TLT/FlrCJCQN6k==|
000001c0  70 53 74 50 0a                                    |pStP.|
000001c5

6   Verification

6.1   Signature verification

Upon reception of an IdFix, a verifier must separate the origin string from the signature on the third semicolon.

A trailing new line must be re-added to the origin string.

Depending on the OpenPGP verification library used, the signature may need to be rewrapped before being passing it to the verifier.

The signature of the origin string must then be verified. An example of verification on the command line is shown below:

$ echo '1;2006-01-02T15:04:05Z;182592280749063001756043640123749365059;' | gpg --verify /tmp/tokid.signature -

gpg: Signature made Mon 23 Feb 2015 09:47:30 PM EST using RSA key ID 3B763E8F
gpg: Good signature from "Julien Vehent (personal) <julien@linuxwall.info>"
gpg:                 aka "Julien Vehent (ulfr) <jvehent@mozilla.com>"

If the signature is valid, the verifier should make sure that the user is authorized to communicate with the endpoint by comparing the user’s key fingerprint with an authorization database. IdFix does not specify how user authorizations should be performed.

6.2   Token expiration

If the signature is valid and the user authorized, the verifier must control the timestamp of the origin string, and discard timestamps that are too young or too old. IdFix recommends to use an acceptance window of 20 minutes: 10 minutes before the verifier time, and 10 minutes after the verifier time.

IdFix assumes that all participants, signers and verifiers, and somewhat synchronized on the same time source. If a participant’s clock desynchronizes too far out of the acceptance window, it will fail to authenticate or verify authentication.

6.3   Token replay

A verifier may require that a token must only be used once. It may do so by keeping track of nonce values for the duration of the timestamp validity. The verifier may issue a 403 Forbidden error code to the signer when duplicate nonces are used. With nonces of at least 64 bits, the chances of nonce collision (1 / 2^64) are considered negligeable, for a validity window of 20 minutes.

Upon reception of a code 403 Forbidden, a signer must generate a new token and retry at least once. The retry on 403 allows verifiers to request new authentication tokens upon conditions that the verifier controls.

7   Standard maintenance

This document is maintained and updated by the author. Changes must be submitted to the author for discussion, acceptance, and release in a new version of the IdFix standard.

8   License

This document and associated source code are subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/.

More information can be found on: https://github.com/jvehent/idfix

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s