我正在尝试在节点服务中创建一个JWT(JSON Web令牌),然后需要在PHP服务中进行检查。
据我所知,我正在根据spec创建令牌,我正在使用Node crypto库加密签名。我已经读过,这些技术之间可靠运行的唯一算法是aes-128-cbc
,这就是我正在使用的算法。
我使用mcrypt_decrypt
运气不错,但仍然没有100%正确,但仍然是失败。另外因为该库已被弃用,我宁愿使用openssl_decrypt
,而我根本无法工作,只是返回false。
secret和init向量都存储在varchar(16)类型的字段中的数据库中,因此它们在两个代码位中都是相同的。我正在使用一个16字节的块大小,所以匹配16byte的秘密和iv。
我尝试了二进制,十六进制和base64格式的不同组合,但是无法让openssl_decrypt函数返回任何错误。
这个问题归结为如何加密节点中的字符串并在PHP中解密?或者我目前使用这些方法有什么问题?
Node v7.4.0
var crypto = require('crypto');
var secret = crypto.randomBytes(16);
var iv = crypto.randomBytes(16);
var header = { type:'JWT', alg: 'aes-128-cbc' };
var payload = { iss: 'auth-token', exp: Date.now() + 86400, token: <some uuid> };
var data = new Buffer(JSON.stringify(header)).toString('base64') + '.' + new Buffer(JSON.stringify(payload)).toString('base64');
var cipher = crypto.createCipheriv('aes-128-cbc', secret, iv);
var encrypted = cipher.update(data, 'utf8', 'base64') + cipher.final('base64');
var JWT = data + '.'+ encrypted;
PHP v7.0.13(也尝试过v7.1.1)
list($header64, $payload64, $sigEnc) = explode('.', $_POST['jwt']);
$header = base64_decode ($header64);
$payload = base64_decode ($payload64);
$signature = openssl_decrypt($sigEnc, 'aes-128-cbc', $secret, null, $iv); // secret and iv are both straight out of the database
更新
我现在改变了我的目标并使用了哈希,这可能是正确的方法。因此,在Node服务中,我使用存储在数据库中的随机密钥创建base64头和有效负载的SHA256哈希。然后在PHP服务中我做同样的事情并比较哈希。这是一种更好的方法,我之前应该采取这种方法。
但是仍然存在一个问题:如何可靠地加密Node中的字符串并在PHP中解密?
答案 0 :(得分:0)
有图书馆,但它们似乎有点过分,应该是相当简单的。
它应该相当简单,但显然它不是。
使用加密技术,您可以很好地理解它,从头开始自己实现算法,或者您不会尝试,因为它的风险太大而无法解决问题。当你犯了一个错误就像你没有任何作用时那样糟糕,但是当它似乎工作但却很弱并且容易受到你没有想到的一些攻击时会更糟。
如果您对安全性非常认真,那么请使用正确的工具来完成工作。在Node中你有:
对于PHP,你有:
有关详细信息,更多工具和更多教程,请参阅https://jwt.io/。
如果你想学习如何在不使用库的情况下正确地做到这一点,那么请阅读这些库的源代码 - 它们都是开源的免费软件。