在PHP中加密字符串并在Node.js中进行解密 [英] Encrypt string in PHP and decrypt in Node.js

查看:1150
本文介绍了在PHP中加密字符串并在Node.js中进行解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过Apache和Node.js服务器之间的不安全的连接发送数据。我需要加密PHP中的数据并在Node.js中进行解密。我花了2天试图让它工作,但是我只是设法让消息签名工作,没有加密。我尝试通过AES128-CBC,AES256-CBC,DES,AES128,AES256作为算法,但没有任何效果。



我在PHP中尝试过:

  $ data = json_encode(Array('mk'=> $ _SESSION ['key'],'algorithm'=>'SHA1' ,'username'=> $ _SESSION ['userid'],'expires'=> $ expires)); 
$ payload = openssl_encrypt($ data,'des','716c26ef');
返回base64_encode($ payload);

在Node.js中:

  var enc_json = new Buffer(response [1],'base64'); 
var decipher = crypto.createDecipher('des','716c26ef');
var json = decipher.update(enc_json).toString('ascii');
json + = decipher.final('ascii');

除了错误的解密数据之外,我收到以下错误:

  TypeError:error:0606508A:数字信封例程:EVP_DecryptFinal_ex:数据不是块长度的倍数

TypeError:error:0606506D:数字信封例程:EVP_DecryptFinal_ex:错误的最终块长度

我需要一个简单的加密,因为数据不太敏感(没有密码或用户数据),但数据只能由接收者读取。密钥长度可以是任何东西,但加密/解密的过程必须尽可能简单,请不要使用IV。

解决方案

处理这样的对称加密,第一步是意识到这可能是后方的一个巨大的痛苦 - 我从来没有像以前那样工作,即使我复制粘贴我自己的代码。这主要是因为加密和解密方法的设计完全是不原谅的,很少给出有用的错误信息。单个空字符,回车符,换行符或动态转换类型可以静默地打击整个过程。



了解这一点,逐步进展。我建议如下:



首先,让PHP单独工作。传入示例文本,加密,立即解密,并将其与原始明文变量的严格相等进行比较。他们完全一样吗?输出两者,它们是相同的类型,并且看起来完全不受压制?注意非打印字符 - 检查长度和字符编码!



现在,再进行上述更多或更少的1个字符的样本文本前一个。这调试块大小/零填充问题 - 这很重要。



如果这样工作 - 很少这样做,很难预测原因,继续使用Node.js



在Node.js中,做同样的事情,就像在PHP中一样,即使它似乎是浪费的努力 - 由于额外的原因,在一瞬间将是明显的。加密和解密,所有在一起,在您的Node.js.它是否符合上述所有相同的条件?



一旦完成,这里就是有趣的部分:在Node.js中独立使用相同的加密方法, PHP,他们都输出给你的最终准备发送的cryptext都产生。



如果一切顺利,他们应该完全一样。如果没有,您的加密实现和方法在系统之间不兼容时遇到问题。一些设置是错误的或冲突的(可能是零填充或其他可能性或IV等),或者您需要尝试其他实现。



如果我不得不盲目猜测,我会说base64编码和解码有一个问题(最常见的是什么问题)。事情往往会完成两次,因为在Web应用程序(通过浏览器)中调试二进制数据类型可能很棘手。有时候,事情会被编码两次,但是只能解码一次,或者一个实现将会自动对自动进行编码/解码,而不会清楚这是在做什么等等。



它也是可能这是Node和PHP之间的零填充实现问题,如下所示: AES加密在Node.js中解密PHP。失败。



最后两个问题是错误代码强烈建议的。加密方法预测精确长度的块大小,如果它们关闭,则表示传递给函数的数据的损坏 - 如果单个额外字符被插入,或者编码被不同地处理,则发生这种情况。



如果您一次通过上述每个操作,确保自己不能赶上,必须检查过程中每一个艰巨的小步骤,应该更加清楚哪里出现问题,然后可以解决问题。


I am sending data through insecure connection between Apache and Node.js servers. I need to encrypt data in PHP and decrypt in Node.js. I've spent 2 days trying to get it to work, however I only managed to get message signing to work, no encryption. I tried passing AES128-CBC, AES256-CBC, DES, AES128, AES256 as algorithms, however nothing worked well..

I tried this in PHP:

$data = json_encode(Array('mk' => $_SESSION['key'], 'algorithm' => 'SHA1', 'username' => $_SESSION['userid'], 'expires' => $expires));
$payload = openssl_encrypt($data, 'des', '716c26ef');
return base64_encode($payload);

And in Node.js:

var enc_json = new Buffer(response[1], 'base64');
var decipher = crypto.createDecipher('des', '716c26ef');
var json = decipher.update(enc_json).toString('ascii');
json += decipher.final('ascii');

And besides wrong decrypted data I get error such as these:

TypeError: error:0606508A:digital envelope routines:EVP_DecryptFinal_ex:data not multiple of block length

TypeError: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

I need a simple encryption as data is not too sensitive (no password or user data), however data should only be read by the recipient. Key length can be anything, but procedure to encrypt/decrypt has to be as simple as possible, please no IVs.

解决方案

When dealing with symmetric encryption like this, the first step is realize that it's probably going to be a huge pain in the rear - I've never, ever had it work right away, even when I was copy pasting my own code. This is mainly because encryption and decryption methods are, by design, utterly unforgiving and rarely give useful error messages. A single null character, carriage return, line feed, or dynamically converted type can silently blow the whole process up.

Knowing this, progress stepwise. I suggest the following:

First, get PHP alone working. Pass in sample text, encrypt it, immediately decrypt it, and compare it with strict equality to the original clear text variable. Are they perfectly the same? Output both, as well - are they the same type and appear perfectly unmolested? Watch out for non-printed characters - check the length and character encoding too!

Now, do the above with one more sample text that is 1 character more or less than the previous one. This debugs block size/zero-padding issues - it matters.

If that's working - and it rarely does right away, for hard to predict reasons, continue to Node.js.

In Node.js, do the same thing as you did in PHP, even if it seems like wasted effort - for extra reasons that will be obvious in a moment. Encrypt and decrypt, all together, in your Node.js. Does it work with all the same provisos given above?

Once that is done, here comes the 'fun' part: using the same encryption methods independently in Node.js and PHP, have them both output to you the 'final' ready-to-transmit cryptext that both produced.

If all is well, they should be perfectly, exactly the same. If they aren't, you have a problem with your encryption implementations and methods not being compatible between systems. Some setting is wrong or conflicting (perhaps with zero padding or a host of other possibilities, or IV, etc), or you need to try a different implementation.

If I had to guess blindly, I'd say there is an issue with the base64 encoding and decoding (it's most commonly what goes wrong). Things tend to get done twice, because it can be tricky to debug binary data types in web applications (through a browser). Sometimes things are being encoded twice but only decoded once, or one implementation will 'helpfully' encode/decode something automatically without being clear that's what it's doing, etc.

It's also possible it's a zero-padding implementation issue between Node and PHP, as suggested here: AES encrypt in Node.js Decrypt in PHP. Fail.

These last two issues are strongly suggested by your error codes. The encryption methods predict block sizes of precise length, and if they are off then that signals corruption of the data being passed to the functions - which happens if a single extra character slipped in, or if encoding is handled differently, etc.

If you step through each of the above one at a time, assuring yourself you can't rush and must check every painstaking tiny little step of the process, it should be much more clear where exactly things are going wrong, and then that can be troubleshooted.

这篇关于在PHP中加密字符串并在Node.js中进行解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆