Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用节点加密进行加密-使用PHP openssl_解密进行解密失败_Php_Node.js_Encryption_Jwt - Fatal编程技术网

使用节点加密进行加密-使用PHP openssl_解密进行解密失败

使用节点加密进行加密-使用PHP openssl_解密进行解密失败,php,node.js,encryption,jwt,Php,Node.js,Encryption,Jwt,我试图在一个节点服务中创建一个JWT(JSONWeb令牌),然后需要在PHP服务中进行检查 据我所知,我正在根据创建令牌,并使用节点库加密签名。我已经读到,在这些技术之间可靠工作的唯一算法是aes-128-cbc,所以这就是我正在使用的算法 我使用了mcrypt\u decrypt,但仍然不是100%正确,这仍然是一个失败。另外,由于该库已被弃用,我宁愿使用我根本无法使用的openssl\u decrypt,它只返回false secret和init向量都存储在数据库中的varchar(16)类

我试图在一个节点服务中创建一个JWT(JSONWeb令牌),然后需要在PHP服务中进行检查

据我所知,我正在根据创建令牌,并使用节点库加密签名。我已经读到,在这些技术之间可靠工作的唯一算法是
aes-128-cbc
,所以这就是我正在使用的算法

我使用了
mcrypt\u decrypt
,但仍然不是100%正确,这仍然是一个失败。另外,由于该库已被弃用,我宁愿使用我根本无法使用的
openssl\u decrypt
,它只返回false

secret和init向量都存储在数据库中的varchar(16)类型字段中,因此它们在两位代码中都是相同的。我使用的是16字节的块大小,因此与16字节的secret和iv匹配

我尝试了二进制、十六进制和base64格式的不同组合,但无法让openssl_解密函数返回除false以外的任何内容

这个问题归结为如何在node中加密字符串并在PHP中解密?或者我目前使用的这些方法有什么问题

节点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;
更新

我现在改变了我的目标,使用了一个哈希,这可能是正确的方法。因此,在节点服务中,我使用存储在数据库中的随机密钥创建base64头和有效负载的SHA256哈希。然后在PHP服务中,我做了同样的操作,并比较了哈希值。这是一个更好的方法,我以前应该采取这种方法

但仍然存在一个问题,即如何在Node中可靠地加密字符串,并在PHP中对其解密


有一些库,但对于应该相当简单的内容来说,它们似乎有点过头了

它应该相当简单,但显然不是

有了密码学,你要么理解得足够好,自己从头开始实现算法,要么你不去尝试,因为出错的风险太大。当你犯了一个错误,就像什么都不起作用时一样,这已经够糟糕的了,但当它似乎起作用,但很脆弱,容易受到一些你没有想到的攻击时,情况就更糟了

如果你对安全问题很认真,那么就使用合适的工具来完成这项工作。在节点中,您有:

对于PHP,您有:

有关更多信息、更多工具和更多教程,请参见


如果你想自己学习如何在不使用库的情况下正确地使用它,那么请阅读这些库的源代码-它们都是开源的,自由软件。

必须有正确实现规范的库。你检查过双方吗?有一些库,但它们似乎有点过于简单。从你的应用程序中拿出一个明文、密钥、iv和密文示例,让我们检查你的工作如何?您也是FITH CoinOp,还是另一个?问题可能在任何地方,比如key和IV的编码。您应该提供一些输入和输出示例。还有,为什么要使用AES-CBC作为一种MAC?通过这样做,您可能通过填充oracle攻击为攻击者提供解密oracle。你应该使用合适的mac,比如HMAC。我觉得如果你想在Node和PHP之间进行双向加密,那么aes-128-cbc是最可靠的算法。但最终,使用散列更有意义。事实上,我使用的是JWT并没有那么重要。我更想问的是,在node中加密字符串并在PHP中解密的最佳方法是什么?我希望这不需要库,因为两种语言都有加密和解密方法。我不是说自己创建一种新的加密形式,只是使用现有的方法。
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