namshi/jose

PHP的JSON对象签名和加密库。

维护者

详细信息

github.com/namshi/jose

源代码

问题

安装次数: 78,613,626

依赖者: 120

建议者: 0

安全性: 2

星标: 1,796

关注者: 63

分支: 133

开放问题: 13

7.2.3 2016-12-05 07:27 UTC

README

弃用通知

嗨,

虽然我们希望能够为世界上所有的开源软件工作,但我们不再积极使用这个库了。这意味着新功能/错误修复等将仅基于外部贡献者的pull请求进行合并,我们强烈建议你寻找一个长期替代方案。

如果你正在寻找一个活跃维护的库,请检查firebase/php-jwt

Build Status Latest Stable Version Total Downloads License

这个库提供了一个JWS(JSON Web Signature)规范的轻量级实现。

先决条件

此库需要PHP 5.5+和OpenSSL库。

它已经使用PHP5.5PHP7.0HHVM进行了测试。

安装

您可以直接从composer / packagist安装此库。

"namshi/jose": "7.0.*"

用法

使用它很简单:想象一下,您想要提供一个能够通过cookie认证用户的服务,而该服务是用javascript构建的;您需要做的是生成一个JWS(在验证凭据后),将其存储为cookie,然后在您想认证该用户的每次调用中从您的JavaScript应用程序传递它。

首先,生成JWS

<?php

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());
}

然后您的JS应用程序可以使用可用的cookie执行认证调用,而不需要发送密码或凭据。

一旦提交请求,您只需验证它是一个有效的调用即可

<?php

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']);
}

小贴士:您可以使用isValid()方法的第二个参数省略,这样jose将尝试使用令牌头中指定的算法验证令牌,但这可能会使您面临一些安全问题。

目前我们建议始终明确设置您想要用于验证令牌的算法。

PHPSECLIB用于RSA验证

您可能会发现您需要在PHP的OpenSSL包装器不工作或OpenSSL根本未安装的环境中使用此库。此库默认使用OpenSSL进行加密,但您可以指定您想要使用PHPSecLib来实现RSA加密的纯PHP实现。

在这种情况下,只需在构建JWS时添加可选的'SecLib'参数即可

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

现在您可以使用PHPSecLib实现的RSA签名。

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

您还可以使用PHPSecLib实现的RSA验证来加载JWS

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

内部机制

为了验证JWS,首先使用公钥验证签名,然后检查令牌是否已过期

为了给JWS一个TTL,只需在负载中使用标准的exp值即可

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

不安全的JWS

您可以通过在加载 JWS 时设置 $allowUnsecure 标志来允许不安全的 JWS。

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

这允许使用 'none' 算法签名的令牌通过,这可能是您不希望做的事情。请谨慎操作 :)

自 2.2.2 版本以来,默认禁用不安全的 JWS。您不应该使用 2.2.2 之前的版本,因为它们存在安全漏洞。更多信息请参阅 这里

使用自定义编码器

如果出于某种原因,您需要以不同的方式编码令牌,您可以在 JWS 实例中注入任何 Namshi\JOSE\Base64\Encoder 的实现。同样,JWS::load() 也接受此类实现作为第二个参数。

实现特定信息

该库提供了一个基础的 JWT 类,它仅实现了 JSON Web Tokens 所需的功能。JWS 类随后扩展了 JWT 类,并添加了使用 JSON Web Signatures 进行签名和验证的实现。SimpleJWS 类扩展了基础 JWS 类,并添加了 TTL 验证和自动包含声明的功能。

主要版本

2.x.x 到 3.x.x

引入了指定加密引擎的能力。在现有的 OpenSSL 实现中添加了对 PHPSecLib 的支持。

3.x.x 到 4.x.x - 不向后兼容

在头中添加了设置自定义属性的能力。将某些声明的自动包含从基础 JWS 类移动到 SimpleJWS 类。

6.x.x - 不向后兼容

6.1.x

  • 放弃了 PHP 5.4 的支持
  • phpseclib 2.0

6.0.x

  • 放弃了 PHP 5.3 的支持
  • 生成 sign-in 输入时不要转义斜杠。这可能会导致使用早期版本的 Jose 生成的令牌不兼容。

7.x.x

7.0.x

将 phpseclib 和 openssl 扩展作为建议的依赖项移动。

测试

为此库编写的测试使用 PHPUnit。在执行 composer install 之后,您可以执行以下命令来运行测试:

./vendor/bin/phpunit

鸣谢

此库受到了 @ritou 初始工作的启发。