JSON Object Signing and Encryption library for PHP.

Related tags

Security jose
Overview

NAMSHI | JOSE

Deprecation notice

Hi there,

as much as we'd like to be able to work on all of the OSS in the world, we don't actively use this library anymore This means that new features / bugfixes / etc will only be merged based on pull requests from external contributors, and we strongly recommend you look for a long-term alternative.

If you're looking for an actively maintained library check firebase/php-jwt out!

Build Status Latest Stable Version Total Downloads License

This library provides a lightweight implementation of the JWS (JSON Web Signature) specification.

Prerequisites

This library needs PHP 5.5+ and the library OpenSSL.

It has been tested using PHP5.5 to PHP7.0 and HHVM.

Installation

You can install the library directly from composer / packagist:

"namshi/jose": "7.0.*"

Usage

Using it is pretty straightforward: imagine that you want to offer a service the ability to authenticate a user via a cookie, and the service is built with javascript; what you would need to do is to generate a JWS (after verifying the credentials once), store it as a cookie and then pass it from your JavaScript app everytime you want to authenticate that user.

First, generate the JWS:

sign($privateKey); setcookie('identity', $jws->getTokenString()); }">


use Namshi\JOSE\SimpleJWS;

if ($username == 'correctUsername' && $pass == 'ok') {
	$user = Db::loadUserByUsername($username);

	$jws  = new SimpleJWS(array(
		'alg' => 'RS256'
	));
	$jws->setPayload(array(
		'uid' => $user->getid(),
	));

    $privateKey = openssl_pkey_get_private("file://path/to/private.key", self::SSL_KEY_PASSPHRASE);
    $jws->sign($privateKey);
    setcookie('identity', $jws->getTokenString());
}

Then your JS app can use the available cookie to execute authenticated calls, without sending passwords or credentials.

Once a request is submitted, you only have to verify that it is a valid call:

isValid($public_key, 'RS256')) { $payload = $jws->getPayload(); echo sprintf("Hey, my JS app just did an action authenticated as user #%s", $payload['uid']); }">


use Namshi\JOSE\SimpleJWS;

$jws        = SimpleJWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");

// verify that the token is valid and had the same values
// you emitted before while setting it as a cookie
if ($jws->isValid($public_key, 'RS256')) {
	$payload = $jws->getPayload();

	echo sprintf("Hey, my JS app just did an action authenticated as user #%s", $payload['uid']);
}

PROTIP: you can omit the second argument of the isValid() method, so jose will try to validate the token with the algorithm specified in the token's header, though this might expose you to some security issues.

For now we recommend to always explicitely set the algorithm you want to use to validate tokens.

PHPSECLIB For RSA Verification

You may find that you need to use this library in an environment where PHP's wrappers for OpenSSL do not work, or OpenSSL simply is not installed. This library uses OpenSSL to encrypt by default, but you can specify that you want to use PHPSecLib for a pure PHP implementation of RSA encryption.

In these cases, simply add the optional 'SecLib' parameter when constructing a JWS:

$jws = new JWS(array('alg' => 'RS256'), 'SecLib');

You can now use the PHPSecLib implementation of RSA signing. If you use a password protected private key, you can still submit the private key to use for signing as a string, as long as you pass the password as the second parameter into the sign method:

$jws->sign(file_get_contents(SSL_KEYS_PATH . "private.key"), 'tests');

You may also load a JWS using the PHPSecLib implementation of RSA verification:

$jws = JWS::load($tokenString, false, $encoder, 'SecLib');

Under the hood

In order to validate the JWS, the signature is first verified with a public key and then we will check whether the token is expired.

To give a JWS a TTL, just use the standard exp value in the payload:

$date    	= new DateTime('tomorrow');
$this->jws  = new SimpleJWS(array('alg' => 'RS256'));
$this->jws->setPayload(array(
	'exp' => $date->format('U'),
));

Unsecure JWSes

You can allow unsecure JWSes by setting the $allowUnsecure flag while loading JWSes:

JWS::load($this->jws->getTokenString(), true);

This allows tokens signed with the 'none' algorithms to go through, which is something you probably don't want to do. Proceed with caution :)

Unsecure JWSes are disabled by default since version 2.2.2. You should not use previous versions other than 2.2.2 as they have a security vulnerability. More info here.

Using a custom encoder

If, for some reason, you need to encode the token in a different way, you can inject any implementation of Namshi\JOSE\Base64\Encoder in a JWS instance. Likewise, JWS::load() accepts such an implementation as a second argument.

Implementation Specifics

The library provides a base JWT Class that implements what is needed just for JSON Web Tokens. The JWS Class then extends the JWT class and adds the implementation for signing and verifying using JSON Web Signatures. The SimpleJWS class extends the base JWS class and adds validation of a TTL and inclusion of automatic claims.

Major Versions

2.x.x to 3.x.x

Introduced the ability to specify an encryption engine. Added support of PHPSecLib to the existing OpenSSL implementation.

3.x.x to 4.x.x - Not Backwards Compatible

Added the ability to set custom properties in the header. Moved automatic inclusion of certain claims into an SimpleJWS class from the base JWS class.

6.x.x - Not Backwards Compatible

6.1.x

  • Dropped support for PHP 5.4
  • phpseclib 2.0

6.0.x

  • Dropped support for PHP 5.3
  • Don't escape slashes when generating signin input. This may render tokens generated with earlier versions of Jose incompatible.

7.x.x

7.0.x

Moved phpseclib and the openssl extension as suggested dependencies.

Tests

Tests are written using PHPUnit for this library. After doing composer install you can execute the following command to run tests:

./vendor/bin/phpunit

Credits

This library has been inspired by the initial work done by @ritou.

Comments
  • setPayload flag and customized header properties

    setPayload flag and customized header properties

    Trying this one again. It provides but fixes the same that was in #20 (which addresses #19).

    It also now adds the ability to set custom properties in the header and have the verification on the other end still work. This was achieved by adding to the constructor for the JWS object a way to pass the header as an array rather than just the two individual options. The constructor change was the least change to the JWS::load method. Alternatively we could do the getHeader/setHeader dance.

    Hopefully my tests have it covered this time. Note that I didn't alter the doc strings for the JWS constructor as I didn't know the best way to do so, nor whether it was worth publicizing. It might be left as an exercise for the reader who wants custom header properties.

    Please have a look and let me know if any changes are needed. Thanks.

    opened by brianjmiller 39
  • Adds ES256, ES384, ES512 signer support

    Adds ES256, ES384, ES512 signer support

    Support for ES256, ES384, ES512 signer. On of the following PHP version required: php-5.4.26 php-5.5.10 php-5.6.0

    The ASN.1 parser from phpseclib is needed for the detection of the curve. In future versions of PHP, this informations is provided by openssl_pkey_get_details. It might be better to add phpseclib to the suggest section of the composer file and adding a check if the ASN.1 parser is present.

    Solves #15

    enhancement 
    opened by dol 19
  • Add support for ES256, ES384, ES512

    Add support for ES256, ES384, ES512

    The PHP core supports EC private keys for signing and verification. This change was introduced in January 2014. Currently this PHP versions support EC private keys: php-5.4.26 php-5.5.10 php-5.6.0

    opened by dol 17
  • HMAC validation is broken in 6.0.4+ on PHP 5.5 and below

    HMAC validation is broken in 6.0.4+ on PHP 5.5 and below

    Release 6.0.4 introduced a change in HMAC::timingSafeEquals() which uses mb_strlen() to calculate string lengths when available, instead of strlen(). Unfortunately, this seems to have broken the function. The problem only becomes apparent in PHP 5.5 and below, since in 5.6.0 and onward it uses PHP's built-in hash_equals() function instead. Commenting out lines 54-57 in Namshi/JOSE/Signer/OpenSSL/HMAC.php fixes it for me:

        //if (\function_exists('mb_strlen')) {
            //$knownLength = \mb_strlen($known, '8bit');
            //$inputLength = \mb_strlen($input);
        //}
    

    But the original commit by @cirpo which introduced this code indicates that strlen() also has problems. I'm not sure what the real fix should be...?

    FWIW, here's how I am generating tokens:

    $sessionId = 12345678;  //  (an integer)
    $key = '********************************';   // (an MD5 hash)
    $algo = 'HS256';
    
    $jws = new SimpleJWS(['alg' => $algo]);
    $jws->setPayload([
        'sub' => $sessionId,
        'iss' => 'My Company'
    ]);
    $jws->sign($key);
    $token = $jws->getTokenString();
    

    And here is what I'm doing to validate them:

    $jws = SimpleJWS::load($token);
    if (!$jws->isValid($key, $algo)) {
        throw new \RuntimeException('Token is invalid!');
    }
    

    Any thoughts?

    opened by curtisdf 14
  • add phpseclib support for RSA encryption

    add phpseclib support for RSA encryption

    We've had trouble with openssl_pkey_get_private() and openssl_pkey_get_public() functions occasionally not recognizing well-formatted public and private keys, for reasons that are difficult to track down. To circumvent the need for these functions, we've allowed for phpseclib support of the RSA algorithms. The code is written according to the style and architecture of the existing library, and is fully tested. It will have no effect on existing code (i.e. it does not change the public API).

    opened by nsfinkelstein 14
  • CS fixes

    CS fixes

    (Continuation of #48)

    I added https://styleci.io/ config and the bridge for php-cs-fixer. I would suggest adding this repo to style-ci and future PR's can be checked for style issues automatically. Style issues can be fixed in accordance with this projects style guide simply by running php-cs-fixer fix . in the repo root directory.

    If you would like to change the style requirements for this project, let me know (https://styleci.readme.io/docs/presets and https://styleci.readme.io/docs/fixers).

    I also removed composer.lock as it was causing issues with travis. It isn't recommended to have this in library repos.

    opened by kbond 13
  • Signature fix

    Signature fix

    This fixes signature creation, the presently generated signature doesn't comply with the RFC and is rejected by other applications/libraries. The reason is that the signature is base64 encoded as a string instead of a hexidecimal representation of octets.

    Convert signature to binary before base64 encode results in the expected signature as verified against the example in RFC 7515 and the http://jwt.io debugger.

    Results may be validated with: echo -n "base64_encoded_header.base64_encoded_payload" | openssl dgst -sha256 -hmac "your_secret" -binary | base64 | tr -- '+=/' '- _'

    opened by stuartm 11
  • Base64 encoder/decoder and tests

    Base64 encoder/decoder and tests

    As described in the draft 21, section 2 of JWT, the Base64 string should be safe and trailing = have to be omitted

    (http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-21#section-2).

    • Base64 class added to encode and decode according to the draft
    • Tests added: test coverage is now 100%
    • Test added to verify that old token will be correctly loaded
    • Moved isExpired method from JWS to JWT
    • constructors modified to use setHeader and setPayload methods
    opened by Spomky 11
  • Fixed security floor in hash_equals

    Fixed security floor in hash_equals

    Fixed security floor. Always better to rely on a third party secure implementation rather than maintaining a separate one that just recently was noticed to be broken.

    opened by GrahamCampbell 10
  • ECDSA signing/verification issues

    ECDSA signing/verification issues

    Hello guys, @jurriaan opened an issue in my library to notify that the I have some problems with my ECDSA signer.

    Looking at your code I saw that you're basically doing the same thing as I, but you have another issue: you're ignoring openssl_verify() return by casting it bool. It's returning -1 (error) and if you run openssl_error_string() you'll get error:0906D06C:PEM routines:PEM_read_bio:no start line as return.

    You can have more information in lcobucci/jwt#30. I'm working on a solution for that and I'll share with you guys :smile:

    opened by lcobucci 9
  • Protected JWS::isExpired

    Protected JWS::isExpired

    I'm using JOSE for handling JWTs in an API client. I would like to be able to check if the token is valid in terms of expiry without running a JWS::isValid. It would be nice if the JWS::isExpired was public. Happy to make a PR if there is a chance of it getting accepted.

    opened by TomAdam 9
  • ECDSA, phpseclib and PHP7: what is the current status?

    ECDSA, phpseclib and PHP7: what is the current status?

    Hi

    I tried using ES512 but got the following error:

    Fatal error: Uncaught InvalidArgumentException: phpseclib 1.0.0(LTS), even the latest 2.0.0, doesn't support PHP7 yet in /.../vendor/namshi/jose/src/Namshi/JOSE/Signer/OpenSSL/ECDSA.php:15

    But phpseclib seems to be alright these days with PHP 7 (their builds pass on PHP 7 and 7.1, see https://travis-ci.org/phpseclib/phpseclib)

    If I comment out the 2 version check blocks in Signer/OpenSSL/ECDSA.php then it seems to be working OK.

    Is the block for PHP 7 still justified? If yes, could it at least be made more explicit in the README of this project? Also, would it be possible to emphasize the need to require phpseclib for ECSDA support in the same README?

    Thanks

    opened by matrey 4
  • "message": "Malformed UTF-8 characters, possibly incorrectly encoded",

    I got : "message": "Malformed UTF-8 characters, possibly incorrectly encoded", when trying to decode a token. $public_key = openssl_pkey_get_public('file://'.__DIR__.'/keys/public.pem'); if (! $signature->isValid($public_key, 'ES256')) { return new Response('Unauthorized', 403); } It's working fine when a generate the token using your library but when the token came from elsewhere (a ruby library) I got that error.

    Any idea?

    opened by michaelchemani 0
  • stop adding iat in payload (optional claim)

    stop adding iat in payload (optional claim)

    fix #111 As mentioned in RFC7519, iat is an optional claim. If iat is added in payload, token that does not contains iat will never pass signature verification.

    opened by jbidzik 3
  • SimpleJWS verification fails if no iat claim

    SimpleJWS verification fails if no iat claim

    According to JWT standard the 'iat' claim i optional. When decoding token (without 'iat') using SimpleJWS then verification of the signature fails. There is a function generateSigninInput in JWT class that return the input that the signature is verified against.

        public function generateSigninInput()
        {
            $base64payload = $this->encoder->encode(json_encode($this->getPayload(), JSON_UNESCAPED_SLASHES));
            $base64header = $this->encoder->encode(json_encode($this->getHeader(), JSON_UNESCAPED_SLASHES));
            return sprintf('%s.%s', $base64header, $base64payload);
        }
    

    But when decoding token (without iat claim) with SimpleJWS, then 'iat' is automatically added to the decoded payload in setPayload method of SimpleJWS so the signinginput is different than was originally in token.

        public function setPayload(array $payload)
        {
            if (!isset($payload['iat'])) {
                $payload['iat'] = time();
            }
            return parent::setPayload($payload);
        }
    
    opened by mamciek 1
Owner
Namshi
The largest fashion e-tailer in the Middle East. #nodejs #javascript #docker #k8s #python #redis #go #kubernetes
Namshi
Replaces Laravel's built-in encryption with an encryption based on AWS KMS

Laravel Kms Encryption Introduction This package replaces Laravel's built-in encryption with an encryption based on AWS KMS. Two major features provid

Arnaud Becher 3 Oct 26, 2021
A petite library of encryption functions for PHP

?? dcrypt A petite library of essential encryption functions for PHP 7.1+. For legacy PHP version support, look here. If you need a dcrypt inspired en

null 96 Oct 6, 2022
A simple php (lumen) app for sharing sensitive text (basically like onetimesecret), but with full end-to-end AES-256-GCM encryption so even the server has no access to the data, and developed with very simple deployment in mind.

A simple php (lumen) app for sharing sensitive text (basically like onetimesecret), but with full end-to-end AES-256-GCM encryption so even the server has no access to the data, and developed with very simple deployment in mind.

Alan Woo 51 Nov 21, 2022
AES 128 bit Encryption and Decryption algorithm excuted purely on PHP with no external libraries.

AES128 Executed with PHP Advanced Encryption Standard (AES) is a specification for the encryption of electronic data established by the U.S National I

Ahmed Mohamed Mostafa 2 Aug 8, 2022
Pretty Good Privacy (PGP) is an encryption program that provides cryptographic privacy and authentication for data communication.

Pretty Good Privacy (PGP) is an encryption program that provides cryptographic privacy and authentication for data communication. PGP is used for signing, encrypting, and decrypting texts, e-mails, files, directories, and whole disk partitions and to increase the security of e-mail communications. Phil Zimmermann developed PGP in 1991.

[sCRiPTz-TEAM] 3 Dec 31, 2021
Password manager featuring client-side encryption, vaults, folders and more.

vaults is a password manager featuring client side AES-256 encryption, PBKDF2 hashing, vaults, password generation & more. Features Technical overview

null 27 Nov 18, 2022
Simplest implementation of RSA algorithm encryption and decryption

Simplest RSA (Rivest–Shamir–Adleman) Simplest implementation of RSA algorithm encryption and decryption. Richard Feynman: What I cannot create, I do n

Max Base 8 Aug 30, 2022
Simple Encryption in PHP.

php-encryption composer require defuse/php-encryption This is a library for encrypting data with a key or password in PHP. It requires PHP 5.6 or new

Taylor Hornby 3.6k Jan 3, 2023
Encryption-free Private Messaging For Flarum

Whisper - Private Messaging for Flarum A Flarum extension. Add private messaging functionality to your Flarum Community! Simple to install, no setting

Charlie 4 Dec 7, 2021
An experimental object oriented SSH api in PHP

PHP SSH (master) Provides an object-oriented wrapper for the php ssh2 extension. Requirements You need PHP version 5.3+ with the SSH2 extension. Insta

Antoine Hérault 355 Dec 6, 2022
TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library

About TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library. By default, a cookie will be used as a storage backend. TCrypto h

timoh 57 Dec 2, 2022
php-chmod is a PHP library for easily changing permissions recursively.

PHP chmod php-chmod is a PHP library for easily changing the permissions recursively. Versions & Dependencies Version PHP Documentation ^1.1 ^7.4 curr

Mathias Reker ⚡️ 5 Oct 7, 2022
A library for generating random numbers and strings

RandomLib A library for generating random numbers and strings of various strengths. This library is useful in security contexts. Install Via Composer

Anthony Ferrara 832 Nov 24, 2022
Fast, general Elliptic Curve Cryptography library. Supports curves used in Bitcoin, Ethereum and other cryptocurrencies (secp256k1, ed25519, ..)

Fast Elliptic Curve Cryptography in PHP Information This library is a PHP port of elliptic, a great JavaScript ECC library. Supported curve types: Sho

Simplito 178 Dec 28, 2022
A multitool library offering access to recommended security related libraries, standardised implementations of security defences, and secure implementations of commonly performed tasks.

SecurityMultiTool A multitool library offering access to recommended security related libraries, standardised implementations of security defences, an

Pádraic Brady 131 Oct 30, 2022
PHP Secure Communications Library

phpseclib - PHP Secure Communications Library Supporting phpseclib Become a backer or sponsor on Patreon One-time donation via PayPal or crypto-curren

null 4.9k Jan 7, 2023
PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically.

PHPGGC: PHP Generic Gadget Chains PHPGGC is a library of unserialize() payloads along with a tool to generate them, from command line or programmatica

Ambionics Security 2.5k Jan 4, 2023
Sodium Compat is a pure PHP polyfill for the Sodium cryptography library (libsodium)

Sodium Compat is a pure PHP polyfill for the Sodium cryptography library (libsodium), a core extension in PHP 7.2.0+ and otherwise available in PECL.

Paragon Initiative Enterprises 817 Dec 26, 2022
A PHP library for counting short DNA sequences for use in Bioinformatics

Helix A PHP library for counting short DNA sequences for use in Bioinformatics. Helix consists of tools for data extraction as well as an ultra-low me

Andrew DalPino 2 Jan 25, 2022