首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP加密和node.js解密

PHP加密和node.js解密
EN

Stack Overflow用户
提问于 2014-10-28 08:14:03
回答 1查看 953关注 0票数 0

通过阅读堆栈溢出的各种答案,我尝试了一些建议和技巧,但是它们似乎是不够的,或者可能有一些基本的东西我错过了。基本上,我试图在php中加密一个值,并将它从JavaScript读取的页面传递到网页,然后发送到节点服务器进行处理。但是,在我用php加密的节点服务器上,我无法获得相同的值。

下面是php代码,php版本为5.5.12,运行在windows 7 64位上:-

代码语言:javascript
运行
复制
function encrypt($string){
 $key = hash("SHA256", '1d417e2ffb2a00a3', true);
 $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
 $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $padding = $blockSize - (strlen($string) % $blockSize);
 $string .= str_repeat(chr($padding), $padding);

 $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$string, MCRYPT_MODE_CBC, $iv);
 $result['cipher'] = base64_encode($ciphertext);
 $result['iv'] = base64_encode($iv);
 return $result;
}

我的node.js版本是0.10.31,运行在windows 7 64位上,代码如下:-

代码语言:javascript
运行
复制
var express = require("express");
var Server = require("http").Server;
var cookie = require("cookie");
var app = express();
var server = Server(app);
var sio = require("socket.io")(server);
var crypto = require('crypto');

sio.sockets.on("connection", function(socket) {
try{
        socket.on('incoming_data', function(data){
            var txt = new Buffer(data.encrypted_text,'base64');
            var key = new Buffer('1d417e2ffb2a00a3','utf8');
            var iv = new Buffer(data.iv,'base64');
            var decipher = crypto.createDecipheriv('aes-128-cbc',key,iv);
            var chunks = [];
            chunks.push(decipher.update(txt,'hex','binary'));
            chunks.push(decipher.final('binary'));
            var fuid = chunks.join('');
            console.log(fuid);
        });
    }catch(e){
        console.log("err:-"+e);
        console.log(e);
    }
});// on connection ends
server.listen(9267, function(){
  console.log('Node server listening on *:9267');
});

process.on('uncaughtException', function(err) {
  console.log("FATAL: "+new Date().getTime()+": "+err);
 });

在nodejs控制台中打印fuid时出现的错误如下:

代码语言:javascript
运行
复制
FATAL: 1414483246855: TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

我现正寻求下列答案的解决办法:

( 1)代码的问题,以及需要修复什么才能在节点服务器上获得与字符串相同的值。

2)将加密的文本和iv连接起来,并将它们作为一个base64编码字符串发送到服务器。因此,希望将它们分离回节点服务器所需的代码准备好传递给加密模块。

3)此代码似乎易受oracle填充攻击的影响。如果你能建议我如何保证它的安全,那就太好了。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-28 09:13:28

问题可能在于您的编码:

代码语言:javascript
运行
复制
chunks.push(decipher.update(txt,'hex','binary'));

hex看起来很奇怪,因为您的输入是缓冲区,而不是字符串。

下面的快速测试工作(也回答了2):

php:

代码语言:javascript
运行
复制
$key = 'secretsecretsecr';
$string = 'attack at dawn';

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $blockSize - (strlen($string) % $blockSize);
$string .= str_repeat(chr($padding), $padding);
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$string, MCRYPT_MODE_CBC, $iv);

$packet = chr($iv_size) . $iv . $ciphertext;

print base64_encode($packet);

节点:

代码语言:javascript
运行
复制
var crypto = require('crypto');

var key = 'secretsecretsecr';
var data = 'paste what the php code printed';

var txt = new Buffer(data,'base64');
var iv_size = txt[0];
var iv = txt.slice(1, iv_size + 1);
var ct = txt.slice(iv_size + 1);
var decipher = crypto.createDecipheriv('aes-128-cbc',key,iv);
var chunks = [];
chunks.push(decipher.update(ct));
chunks.push(decipher.final());

console.log(chunks.join(''));

传递iv大小,您也可以简单地在节点端硬编码它。

关于3),我绝不是专家,据我所读到的解决办法是用HMAC对加密的数据包签名,以确保它们来自您的应用程序,而不是来自"oracle“(http://www.ietf.org/id/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.txt)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26603544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档