JWT(JSON Web Token)的签名算法主要有几种,其中最常见的是HMAC(Hash-based Message Authentication Code)算法族和RSA(Rivest–Shamir–Adleman)或ECDSA(Elliptic Curve Digital Signature Algorithm)等公钥加密算法。
HMAC签名算法:
HMAC是一种基于密钥的消息认证码算法,它使用一个密钥与消息内容结合生成一个签名。HMAC可以用于任何迭代散列函数,如SHA256,结合一个密钥来加强安全性。HMAC是对称的,意味着加密和解密使用相同的密钥。
RSA和ECDSA签名算法:
RSA和ECDSA是非对称加密算法,它们使用一对密钥:公钥和私钥。私钥用于签名JWT,公钥用于验证签名。这种方式的优点是私钥可以安全地保密,而公钥可以公开分发给任何人,用于验证签名的真实性。
底层原理:
- 对于HMAC,其原理是利用哈希函数(如SHA256)与密钥相结合,为数据生成一个固定长度的哈希值,这个哈希值就是签名。接收者可以使用相同的密钥和哈希函数重新计算哈希值,然后与附带的签名进行比较,以验证数据的完整性和真实性。
- 对于RSA和ECDSA,签名是通过私钥对数据进行加密产生的,这个加密过程是不可逆的。公钥用于解密签名,但不用于解密数据内容本身。如果解密成功,即说明数据是由相应的私钥签名的,从而验证了签名者的身份和数据完整性。
通俗解释:
可以把签名算法想象成是一种特殊的印章。HMAC算法就像是你有一个私人的印章,你每写一封信都会用这个印章在信上盖章,收信人可以用同样的印章来核对这个章是不是真的,确认信没有被动过。而RSA和ECDSA算法就像是你有一个非常特别的印章,这个印章有两部分,一个公开的部分(公钥)和一个私密的部分(私钥)。你可以用私密的部分(私钥)来盖章(签名),而任何人都可以用公开的部分(公钥)来核对这个章(签名)是否真实。
PHP实例代码:
以下是使用HMAC SHA256和RSA算法签名和验证JWT的PHP代码示例。
HMAC SHA256签名示例:
<?php $key = "your_secret_key"; // HMAC密钥 $payload = array( "sub" => "1234567890", "name" => "John Doe", "exp" => time() + 3600 // 1小时后过期 ); // 使用HMAC SHA256算法签名JWT $jwt = JWT::encode($payload, $key, 'HS256'); echo "HMAC SHA256签名的JWT: " . $jwt . PHP_EOL; // 验证签名 try { $decoded = JWT::decode($jwt, $key, array('HS256')); echo "JWT验证成功!" . PHP_EOL; print_r($decoded); } catch (Exception $e) { echo "JWT验证失败: " . $e->getMessage() . PHP_EOL; } ?>RSA签名示例:
<?php $privateKey = "..."; // RSA私钥 $publicKey = "..."; // RSA公钥,用于验证签名 $payload = array( "sub" => "1234567890", "name" => "John Doe", "exp" => time() + 3600 // 1小时后过期 ); // 使用RSA算法签名JWT $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "RSA签名的JWT: " . $jwt . PHP_EOL; // 验证签名 try { $decoded = JWT::decode($jwt, $publicKey, array('RS256')); echo "JWT验证成功!" . PHP_EOL; print_r($decoded); } catch (Exception $e) { echo "JWT验证失败: " . $e->getMessage() . PHP_EOL; } ?>注意:在实际使用中,私钥和公钥应该是从安全的来源获取,并且妥善保管。这里的...需要替换成你实际的密钥。另外,为了使用RSA签名,你需要先生成RSA密钥对。以上示例代码假设你已经安装了firebase/php-jwt库。如果没有安装,你可以通过Composer进行安装。