JWT
1.基础概念
JSON Web Token,一种安全认证机制:头部.载荷.签名
base64url编码:base64编码后,去除=,+改为-,/改为_
头部
{
"alg": "签名算法(HS256(对称加密)、RS256(私钥加密、公钥解密)等)",
"typ": "JWT"
}
{"alg":"HS256","typ":"JWT"}进行base64url编码:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
载荷
由声明组成,可以自定义或用预定义声明(iss签发者、sub主题、aud接收方、exp过期时间、nbf最早处理时间、iat签发时间、jti ID)
{
"name": "admin"
}
{"name":"admin"}进行base64url编码:eyJuYW1lIjoiYWRtaW4ifQ
签名
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4ifQ进行加密再进行base64url编码的结果
2.绕过
1.alg改为none
2.alg从RS256改为HS256,然后用公钥加密(python和nodejs库不同)
3.爆破
import jwt
head = {"alg":"HS256","typ":"JWT"}
payload = {"name":"admin"}
keys = []
for key in keys:
token = jwt.encode(headers = head, payload = payload, key = key)
if token == '':
print(key)
3.PHP JWT实现
php-jwt库
安装
apt-get install php-curl
apt-get install php-dev
apt-get install composer
cd /var/www/html
composer require firebase/php-jwt
实现
HS256,例:
use \Firebase\JWT\JWT;
use \Firebase\JWT\Key;
include('vendor/autoload.php'); // 加载JWT库
$payload = ['name'=>'admin', 'exp'=>time()+3600]; // 载荷
$jwt = JWT::encode($payload, 'key', 'HS256'); // 生成JWT
echo $jwt.'<br>';
// 验证JWT
$plaintext = JWT::decode($jwt, new Key('key', 'HS256')); // 解密
$plaintext = (array)$plaintext; // 转数组
if ($plaintext['name'] == 'admin' && time() < $plaintext['exp']) {
echo 'Token有效';
}
RS256,例:
<?php
use \Firebase\JWT\JWT;
use \Firebase\JWT\Key;
include('vendor/autoload.php'); // 加载JWT库
// ssh-keygen -t rsa -N '' -m pem -f key.pem
// chmod 777 key.pem
$privateKey = openssl_pkey_get_private(file_get_contents('./key.pem'), 'Your Key'); // 生成私钥
$payload = ['name'=>'admin', 'exp'=>time()+3600]; // 载荷
$jwt = JWT::encode($payload, $privateKey, 'RS256'); // 生成JWT
echo $jwt.'<br>';
// 验证JWT
$publicKey = openssl_pkey_get_details($privateKey)['key']; // 生成公钥
$plaintext = JWT::decode($jwt, new Key($publicKey, 'RS256')); // 解密
$plaintext = (array)$plaintext; // 转数组
if ($plaintext['name'] == 'admin' && time() < $plaintext['exp']) {
echo 'Token有效';
}